zoukankan      html  css  js  c++  java
  • cf949C

    题意简述:有n个点,每一个点都有一个权值,然后有m个条件,每一个条件是a[x]!=a[y],让选择最少的点且至少选择1个,然后让这个点的权值+1,使得条件仍满足

    所有数对k取模

    题解:如果a[x]+1=a[y]那么x向y连边,a[y]+1=a[x]那么y向x连边,此时答案等于缩点之后出度为0的分量中点最少的一个

    #include<bits/stdc++.h>
    #define forn(i, n) for (int i = 0 ; i < int(n) ; i++)
    #define fore(i, s, t) for (int i = s ; i < (int)t ; i++)
    #define fi first
    #define se second
    #define all(x) x.begin(),x.end()
    #define pf2(x,y) printf("%d %d
    ",x,y)
    #define pf(x) printf("%d
    ",x)
    #define each(x) for(auto it:x)  cout<<it<<endl;
    #define pi pair<int,int>
    using namespace std;
    typedef long long ll;
    const int maxn=1e6+5;
    const int maxm=2e5+5;
    const int inf=1e9;
    int head[maxn],ver[maxm],nex[maxm],tot;
    void inline AddEdge(int x,int y){
    	ver[++tot]=y,nex[tot]=head[x],head[x]=tot;
    }
    int dfn[maxn],low[maxn],num,sccnum,scc[maxn],s[maxn],d[maxn],cnt[maxn],top;
    void Tarjan(int x){
    	low[x]=dfn[x]=++num;
    	s[++top]=x;
    	for(int i=head[x];i;i=nex[i]){
    		int y=ver[i];
    		if(!dfn[y]) {
    			Tarjan(y);
    			low[x]=min(low[x],low[y]);
    		}
    		else if(!scc[y]) low[x]=min(low[x],dfn[y]);
    	}
    	if(low[x]==dfn[x]){
    		sccnum++;
    		while(s[top]!=x){
    			scc[s[top]]=sccnum;
    			top--;
    			cnt[sccnum]++;
    		}
    		cnt[sccnum]++;
    		scc[s[top]]=sccnum;
    		top--;
    	}
    }
    int n,m,k,a[maxn];
    int main(){
    	cin>>n>>m>>k;
    	for(int i=1;i<=n;i++)
    		scanf("%d",&a[i]);
    	for(int i=0;i<m;i++){
    		int x,y;
    		scanf("%d%d",&x,&y);
    		if((a[x]+1)%k==a[y]) AddEdge(x,y);
    		if((a[y]+1)%k==a[x]) AddEdge(y,x);
    	} 
    	for(int i=1;i<=n;i++)
    		if(!dfn[i]) Tarjan(i);
    	for(int x=1;x<=n;x++)
    		for(int i=head[x];i;i=nex[i]){
    			int y=ver[i];
    			if(scc[x]!=scc[y]) {
    				d[scc[x]]++;
    			}
    		}
    	int idx=0;
    	cnt[idx]=1e9;
    	for(int i=1;i<=n;i++){
    		if(d[scc[i]]==0 && cnt[scc[i]]<cnt[scc[idx]])
    			idx=i;
    	}
    	cout<<cnt[scc[idx]]<<endl;
    	for(int i=1;i<=n;i++)
    		if(scc[idx]==scc[i]) cout<<i<<' ';
    	cout<<endl;
    	return 0;
    }
    

      

  • 相关阅读:
    软件工程第一次结对作业
    软件工程第二次作业
    vue之vuex
    ceshi
    第3次 结构与部分
    第二次作业
    获得领跑衫感言
    期末总结
    第十四,十五周作业
    第七周作业
  • 原文地址:https://www.cnblogs.com/033000-/p/12345990.html
Copyright © 2011-2022 走看看