zoukankan      html  css  js  c++  java
  • codeforces 1217D Coloring Edges 题解

    挺有意思的一道题。

    首先如果没有环,那么一种颜色染完所有边,答案为 (1)
    这里我直接用拓扑排序判断有没有环了。

    如果有环,一种颜色肯定是不行了。我们发现对于每一个环,可以视为从一个点出发,经过另一些点,再回到这个点的路径。
    这里我们给每一个点任意赋予一个高度(就是赋予一个权值..吧),同时保证所有点高度不同,这时候我们发现从一个点 (x) 出发,走完第一步之后,要么是到达了高度比原来更高的点,要么到达了高度比原来更低的点,而最后我们要回到 (x),如果第一步往高处走了,环上总有至少一步需要往低处走,不然一定无法回到 (x)。另一种情况同理。

    总而言之,每一个环必定同时包含走向更高高度的边和走向更低高度的边。

    所以把高往低走的边染色为 (1),低往高走的染色为 (2)

    然后这题就做完了。

    高度怎么赋?随便怎么搞都可以,只要两两不同就行了。
    这里我为了方便直接用了点的编号

    代码:

    // 头文件省略了
    using namespace std;
    typedef long long LL;
    
    vector <LL> G[200005];
    LL vis[200005],in[200005] = {0};
    LL cnt = 0,n,m;
    
    void tp_sort(){
    	queue <LL> q;
    	for(LL i = 1;i <= n;i ++){
    		if(!in[i]){
    			cnt --;
    			q.push(i);
    		}
    	}
    	while(!q.empty()){
    		LL u = q.front(); q.pop();
    		for(LL i = 0;i < G[u].size();i ++){
    			LL v = G[u][i]; in[v] --;
    			if(!in[v]){
    				cnt --;
    				q.push(v);
    			}
    		}
    	}
    } // 拓扑排序
    
    LL u[200005],v[200005],col[200005];
    
    int main(){
    	cin >> n >> m;
    	for(LL i = 1;i <= m;i ++){
    		cin >> u[i] >> v[i];
    		G[u[i]].push_back(v[i]); in[v[i]] ++;
    	}
    	cnt = n; tp_sort();
    	if(!cnt){
    		cout << 1 << endl;
    		for(LL i = 1;i <= m;i ++) cout << 1 << (i == m ? '
    ' : ' ');
    		return 0; // 判断无环的情况
    	}
    	
    	for(LL i = 1;i <= m;i ++){
    		if(v[i] < u[i]) col[i] = 2;
    		if(v[i] > u[i]) col[i] = 1;
    	} // 有环,直接根据点编号大小关系给边染色
    	cout << 2 << endl;
    	for(LL i = 1;i <= m;i ++) cout << col[i] << (i == m ? '
    ' : ' ');
    	return 0;
    }
    //
    
  • 相关阅读:
    开源文档管理系统LogicalDOC测试报告---安装篇
    QualityCenter的备份
    hudson任务配置说明
    windows server 2003断开远程之后自动注销用户
    使用javaservice 将jboss 注册为服务
    mysql主从同步配置(windows环境)
    更改MYSQL数据库不区分大小写表名
    MySQL的mysqldump工具的基本用法
    MySql中delimiter的作用是什么?
    Ubuntu安装配置Mysql
  • 原文地址:https://www.cnblogs.com/IltzInstallBI/p/12744267.html
Copyright © 2011-2022 走看看