简单记录 Part1.1

21 篇文章 0 订阅
6 篇文章 0 订阅

1.CF1328D Carousel

分类讨论:
1:为偶数,输出12121212…

2:为奇数,
但是有两个连续的图形相同,从此位置断开输出121212…
且没有任何相邻的图形相同,输出121212…3

#include<bits/stdc++.h>
#define int long long
using namespace std;
constexpr int maxn=4e5+5,inf=0x3f3f3f3f,mod=1e9+7;
int n,m,t,a[maxn],res[maxn];

signed main(){
	cin>>t;
	while(t--){
		cin>>n;
		for(int i=1;i<=n;i++){
			cin>>a[i];
		}
		int flag1=0,flag2=0;
		a[n+1]=a[1];
		int pos;
		for(int i=1;i<=n;i++){
			if(a[i]==a[i+1])flag1=1,pos=i;
			else flag2=1;
		}
		if(!flag2){
			puts("1");
			for(int i=1;i<=n;i++)printf("1 ");
			puts("");
		}
		else{
			if(n%2==0){
				puts("2");
				for(int i=1;i<=n;i++){
					printf("%d ",1+(i&1));
				}
				puts("");
			}
			else if(flag1){
				puts("2");
				for(int i=1;i<=n;i++){
					res[(pos+i-1)%n+1]=i&1;
				}
				for(int i=1;i<=n;i++){
					printf("%d ",res[i]+1);
				}
				puts("");
			}
			else{
				puts("3");
				for(int i=1;i<=n-1;i++){
					printf("%d ",1+(i&1));
				}
				puts("3");
			}
		}
	}
} 

2.CF1334D Minimum Euler Cycle

题意:求最小字典序欧拉回路的l到r个节点
经过观察可以发现
12 13 14 15 23 24 25 34 35 45 1

#include<bits/stdc++.h>
#define int long long
using namespace std;
constexpr int maxn=4e5+5,inf=0x3f3f3f3f,mod=1e9+7;
int n,l,r,t;
signed main(){
	cin>>t;
	while(t--){
		cin>>n>>l>>r;
		int pos=1;
		int base=0;
		for(int i=(n-1)*2;i;base+=i,i-=2){
			for(int j=max(base+1,l);j<=min(base+i,r);j++){
				if(j%2)printf("%lld ",n-i/2);
				else printf("%lld ",(j-base)/2+(n-i/2));
			}
		}
		if(base==r-1)puts("1");
		else puts("");
	}
	return 0;
} 

3.CF1324F Maximum White Subtree

简单换根dp

#include<bits/stdc++.h>
using namespace std;
constexpr int maxn=2e5+5,inf=0x3f3f3f3f;
int n,m,k,t,cnt,tt;
int size[maxn];
vector<int>e[maxn];
void dfs1(int u,int fa){
	for(auto v:e[u]){
		if(v==fa)continue;
		dfs1(v,u);
		if(size[v]>0)size[u]+=size[v];
	}
}
void dfs2(int u,int fa){
	for(auto v:e[u]){
		if(v==fa)continue;
		if(size[v]>0){
			size[v]=max(size[v],size[u]);
		}
		else{
			size[v]=max(size[v],size[u]+size[v]);
		}
		dfs2(v,u);
	}
}
int main(){
	cin>>n;
	int flag=0;
	for(int i=1;i<=n;i++){
		cin>>size[i];
		if(!size[i])size[i]=-1;
	}
	for(int i=1;i<=n-1;i++){
		int u,v;
		cin>>u>>v;
		e[u].push_back(v);
		e[v].push_back(u);
	}
	dfs1(1,1);
	dfs2(1,1);
	for(int i=1;i<=n;i++){
		printf("%d ",size[i]);
	}
}

4.CF721C Journey

题意:给出一个 n n n个点 m m m条边的有向无环图。
问从 1 1 1 n n n,在距离不超过 k k k的情况下最多经过多少点,并输出一个方案。

思路:spfa

#include<bits/stdc++.h>
using namespace std;
constexpr int maxn=5005,inf=0x3f3f3f3f;
int id;
int n,m,k,mm,dis[maxn][maxn];
bool inque[maxn][maxn];
int pre[maxn][maxn];
struct edge{
	int v,w;
};
vector<edge>e[maxn];
void pri(int now,int res){
	if(pre[now][res]==0){
		if(now==1){
			printf("1 ");
		}
		return;
	}
	pri(pre[now][res],res-1);
	printf("%d ",now);
}
void spfa(){
	memset(dis,inf,sizeof dis);
	dis[1][0]=0;
	queue<pair<int,int>>q;
	q.push({1,0});
	while(!q.empty()){
		auto x=q.front();
		q.pop();
		int u=x.first;
		int res=x.second;
		inque[u][res]=0;
		for(auto y:e[u]){
			int v=y.v;
			int w=y.w;
			if(dis[v][res+1]>dis[u][res]+w&&dis[u][res]+w<=k){
				dis[v][res+1]=dis[u][res]+w;
				pre[v][res+1]=u;
				if(!inque[v][res+1]){
					q.push({v,res+1});
					inque[v][res+1]=1;
				}
			}
		}
	}
}
signed main(){
	cin>>n>>m>>k;
	for(int i=1;i<=m;i++){
		int u,v,w;
		cin>>u>>v>>w;
		e[u].push_back((edge){v,w});
	}
	spfa();
	for(int i=n;i>=0;i--){
		if(dis[n][i]<=k){
			mm=i;
			break;
		}
	}
	cout<<mm+1<<endl;
	pri(n,mm);
	return 0;
} 

5.CF404C Restore Graph

模拟

6.CF61D Eternal Victory

从根节点开始,遍历所有节点的最短路

思路:画图模拟可以发现是需要找到最长链,sum*2-最长链长度即可

#include<bits/stdc++.h>
#define int long long
using namespace std;
constexpr int maxn=1e5+5,inf=0x3f3f3f3f;
typedef pair<int,int>pii;
int n,m,k,vis[maxn],dis[maxn],du[maxn];
struct edge{
	int v,w;
};
vector<edge>e[maxn];
priority_queue<pii,vector<pii>,greater<pii>>q;
inline void dij(int s){
	memset(dis,inf,sizeof dis);
	memset(vis,0,sizeof vis);
	dis[s]=0;
	q.push({0,s});
	while(!q.empty()){
		auto x=q.top();
		q.pop();
		int u=x.second;
		if(vis[u])continue;
		vis[u]=1;
		for(auto y:e[u]){
			int v=y.v;
			int w=y.w;
			if(dis[v]>dis[u]+w){
				dis[v]=dis[u]+w;
				q.push({dis[v],v});
			}
		}
	}
}
signed main(){
	cin>>n;
	int sum=0;
	int cnt=0;
	for(int i=1;i<=n-1;i++){
		int u,v,w;
		scanf("%lld%lld%lld",&u,&v,&w);
		e[u].push_back((edge){v,w});
		e[v].push_back((edge){u,w});
		du[u]++,du[v]++;
		sum+=w;
	}
	dij(1);
	int mm=0;
	for(int i=1;i<=n;i++){
		if(du[i]==1)cnt++;
	}
	for(int i=2;i<=n;i++){
		if(du[i]==1){
			mm=max(mm,dis[i]);
		}
	}
	cout<<sum*2-mm;
}

7.CF1213G Path Queries

有一棵 n n n 个点的树,每条边都带权。

她会问你 m m m 个问题,每次给你一个正整数 q q q,求最大权值不大于 q q q 的简单路径数量。

需要注意的是,对于一个点对 ( u , v ) (u,v) (u,v) 只记一次,单独一个点不算路径。

思路:并查集,将所有询问和边权排序,累计答案输出即可

8.CF1176D Recover it!

还没写

9.CF743D Chloe and pleasant prizes

树形DP

#include<bits/stdc++.h>
#define int long long
using namespace std;
constexpr int maxn=2e5+5,inf=1ll<<61;
typedef pair<int,int>pii;
int n,m,k,a[maxn],f[maxn],res[maxn],mm,ans=-inf;
int dp[maxn];
vector<int>e[maxn];
void dfs(int u,int fa){
	dp[u]=-inf;
	f[u]=a[u];
	for(auto v:e[u]){
		if(v==fa)continue;
		dfs(v,u);
		f[u]+=f[v];
		if(dp[u]>-inf)ans=max(ans,dp[u]+dp[v]);
		dp[u]=max(dp[u],dp[v]);
	}
	dp[u]=max(f[u],dp[u]);
}
signed main(){
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>a[i];
	}
	for(int i=1;i<n;i++){
		int u,v;
		cin>>u>>v;
		e[u].push_back(v);
		e[v].push_back(u);
	}
	dfs(1,1);
	if(ans>-inf)cout<<ans;
	else cout<<"Impossible";
}

10.CF1076D Edge Deletion

在最短路径树简谈中已写

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值