• 题解 CF1407E 【Egor in the Republic of Dagestan】


    CF1407E 题解

    题目大意

    有一张图,每条边都有一个权值 (0/1)

    你现在需要给点染色 (0/1) ,一条边可以经过有且仅当它的起始点的颜色和边的颜色一样。

    问你可不可以使得从 (1 o n) 不存在连通的路径,如果不可以,求最短路径,路径长度定义为这条路径上边的数量。

    题解

    这题作为 (2E) 来说还是挺简单的,算是白给吧。

    你考虑一条边什么时候才可以连通,这是取决于它的前一个点。

    但是如果你正序的去遍历的话,你肯定会先遍历到它的起始点,但是这个点可能和多个边对应,那怎么处理?

    那我们就反着来!!

    (n) 号点开始遍历,如果当前的 (2) 点之间只有一种颜色的边,表示你可以把这条路堵死,那就把它堵死。

    如果有 (2) 种颜色,那么他的节点也就不是什么很重要的问题了。

    你会说一个节点会连接多条边,为什么对其他的边没有影响呢?

    因为我们做的是 (BFS) 每个节点只要统计最短的路径,而且每次先被遍历到的一定比下一次遍历到的路径要短,所以直接 (BFS) 就可以了。

    #include <iostream>
    #include <queue>
    #include <string.h>
    #include <stdio.h>
    using namespace std;
    const int maxn = 5e5 + 10;
    
    int n, m, x, y, w, cnt, col[maxn], dis[maxn], vis[maxn], d[maxn], head[maxn];
    struct node {
        int nxt, to, val;
    } e[maxn << 1];
    void add(int x, int y, int w) {
    	e[++ cnt].to = y; e[cnt].nxt = head[x]; head[x] = cnt; e[cnt].val = w;
    }
    queue<int>q;
    int main() {
        // cin >> n >> m;
        scanf("%d%d", &n, &m);
    	for(int i = 1; i <= m; ++ i) {
    		// cin >> x >> y >> w;
            scanf("%d%d%d", &x, &y, &w);
            add(y, x, w);
    	}
    	if(n == 1) {
            cout << "0" << endl << "0";
    		return 0;
    	}
    	memset(col, -1, sizeof(col));
    	q.push(n);
        vis[n] = 0;
    	while(q.size()) {
    		int x = q.front(); q.pop();
    		if(x == 1) {
                break;
            }
            for(int i = head[x]; i; i = e[i].nxt) {
                int v = e[i].to;
                if(vis[v]) continue;
    			if(col[v] == -1 || col[v] == 1 - e[i].val) {
    				col[v] = 1 - e[i].val;
    			}
                else {
    				q.push(v);
    				d[v] = d[x] + 1;
    				vis[v] = 1;
    		    }
            }
    	}
        if(d[1]) {
            cout << d[1] << endl;
        }
        else {
            cout << "-1" << endl;
        }
    	for(int i = 1; i <= n; ++ i) {
    		if(col[i] == -1) {
                cout << "0";
            }
    		else {
                cout << col[i];
            }
    	}
    	return 0;
    }
    
  • 相关阅读:
    数据库基本操作
    守护线程
    线程使用的场景
    创建多线程
    用正则表达式去截取网页里文字的方法。参数为读取的网页源代码
    文章生成器,Split方法截取字符串。从硬盘读取文件,和向硬盘存储文件参考代码
    winform 阶段学习总结
    Windowform 窗体关联数据库存储,读取图片,参考代码
    windows form窗体应用程序,建一个记事本参考代码,重点是打开,保存,另存为
    js实现相册翻页,滚动,切换,轮播功能
  • 原文地址:https://www.cnblogs.com/Flash-plus/p/13834172.html
Copyright © 2020-2023  润新知