• [51NOD 1967] 路径定向


    题目传送-51NOD1967

    题意:

    给出一个有向图,要求给每条边重定向,使得定向后出度等于入度的点最多,输出答案和任意一种方案.
    (N≤10^5,M≤3*10^5, Xi,Yi≤N)

    题解:

    考虑
    先当每条边双向。
    如果这个图的所有点的度都是偶数,那么欧拉路径跑一下就行了
    考虑度为奇数的点:连接所有度为奇数的点,使其成为偶数点,显然不会影响正确性
    留个坑。。这个算法的总结。。。

    过程:

    没有过程。。

    代码:

    const int N=100010,M=600010;
    int n,m;
    int head[N],nxt[M<<1],to[M<<1],vis[M<<1],lst=1;
    int cur[N];
    int in[N];
    inline void adde(int x,int y) {
    	nxt[++lst]=head[x]; to[lst]=y; head[x]=lst;
    }
    bool used[N];
    int sta[M<<1],top=0;
    void dfs(int u) {
    	for(int &i=cur[u];i;i=nxt[i])
    		if(!vis[i] && !vis[i^1]) {
    			vis[i]=1;
    			dfs(to[i]);
    			break;
    		}
    }
    inline void Fluery(int S) {
    	sta[++top]=S;
    	while(top) {
    		int u=sta[top--];used[u]=1;
    		bool can=0;
    		for(int &i=cur[u];i;i=nxt[i])
    			if(!vis[i] && !vis[i^1]) {can=1; break;}
    		if(can) dfs(u);
    	}
    }
    
    int seq[N],tot;
    signed main() {
    	read(n); read(m);
    	for(int i=1;i<=m;i++) {
    		int x,y; read(x); read(y);
    		adde(x,y); adde(y,x);
    		++in[x]; ++in[y];
    	}
    	for(int i=1;i<=n;i++)
    		if(in[i]&1) {
    			seq[++tot]=i;
    		}
    	int ans=n-tot;
    	for(int i=1;i<=tot;i+=2) {
    		adde(seq[i],seq[i+1]); adde(seq[i+1],seq[i]);
    	}
    	memcpy(cur,head,sizeof(head));
    	for(int i=1;i<=n;i++)
    		if(!used[i]) Fluery(i);
    	printf("%d
    ",ans);
    	for(int i=1;i<=m;i++) {
    		printf("%d",(vis[i*2] ? 0 : 1));
    	}
    	return 0;
    }
    

    用时:15min(不算学算法)

  • 相关阅读:
    Hive 导入、导出数据
    mysql 命令行参数说明
    mysql 查看表信息
    python之冒泡排序
    python之选择排序
    python之快速排序
    光荣之路测试开发面试linux考题之四:性能命令
    测试开发linux面试之三:后台进程之操作
    测试开发面试的Linux面试题总结之二:常用命令
    测试开发面试的Linux面试题总结之一:vim使用方法
  • 原文地址:https://www.cnblogs.com/functionendless/p/9535237.html
Copyright © 2020-2023  润新知