zoukankan      html  css  js  c++  java
  • @atcoder


    @description@

    给出一个有向图,对每条边都做一次询问:

    翻转这条边后,对原图的强连通分量是否有影响?

    点的个数 N ≤ 1000,边的个数 M ≤ 200000。

    原题传送门。

    @solution@

    看到 5s 时限,大胆猜测时间复杂度 O(NM)。

    一条边 u->v 翻转造成的影响:
    如果这条边在强连通分量里(等价于存在路径 v 到 u),当不存在另一条路径 u 到 v 时,则翻转后强连通减少。
    如果不在,当存在另一条路径 u 到 v 时,则翻转后强连通增加。

    也就是说对于一条边 u->v,我们需要判两个东西:是否存在 v 到 u 的路径;是否存在另一条 u 到 v 的路径。

    前一个暴力 O(NM) 就可以做了,不需要再另外写一个强连通。
    至于后一个。我们考虑另一条路径意味着什么:存在一条以 u 为起点且中途不经过 u,第一条边不是 u->v 的路径。

    那么对于每一个点 u 搜索全图,判断到达每个点 x 的路径第一条边是否只有一种。
    这个随便怎么搜都可以,因为每个点的状态只会被更新两次(只有一种,多于一种)。

    @accepted code@

    #include <cstdio>
    #include <vector>
    #include <algorithm>
    using namespace std;
    
    const int MAXN = 1000;
    const int MAXM = 200000;
    
    vector<int>G[MAXN + 5]; int to[MAXM + 5];
    void addedge(int u, int i) {G[u].push_back(i);}
    
    int tag[MAXN + 5], que[2*MAXN + 5];
    bool ans1[MAXM + 5], ans2[MAXM + 5];
    
    int n, m;
    int main() {
    	scanf("%d%d", &n, &m);
    	for(int i=1;i<=m;i++) {
    		int a; scanf("%d%d", &a, &to[i]);
    		addedge(a, i);
    	}
    	for(int i=1;i<=n;i++) {
    		for(int j=1;j<=n;j++) tag[j] = 0;
    		int s = 1, t = 0;
    		for(int p=0;p<G[i].size();p++)
    			tag[que[++t] = to[G[i][p]]] = G[i][p];
    		while( s <= t ) {
    			int x = que[s++], y = tag[x];
    			for(int p=0;p<G[x].size();p++) {
    				int q = to[G[x][p]];
    				if( q != i ) {
    					if( tag[q] != -1 ) {
    						if( tag[q] == 0 )
    							tag[que[++t] = q] = y;
    						else if( tag[q] != y )
    							tag[que[++t] = q] = -1;
    					}
    				}
    				else ans1[G[x][p]] = 1;
    			}
    		}
    		for(int p=0;p<G[i].size();p++)
    			if( tag[to[G[i][p]]] == -1 ) ans2[G[i][p]] = 1;
    	}
    	for(int i=1;i<=m;i++)
    		puts(ans1[i] ^ ans2[i] ? "diff" : "same");
    }
    

    @details@

    像这种稠密图,用 vector 存储比链式前向星存储更快(对 cache 更友好)。特别是这种常数影响极大的题。

    至于 cache 是个啥。。。根据我 THUWC2020 的参赛所学,大概就是除了内存以外, cpu 自己有一个更近的临时空间叫 cache。
    如果你一直访问同一个元素的话,对 cache 是非常友好,因此也就会更快。

  • 相关阅读:
    JavaScript使用技巧精萃
    小谈js事件
    更深入地了解H1N1型流感病毒
    Oracle的一些常用操作
    JS刷新页面
    asp.net Excel导入&导出(转)
    [转]我的敏捷开发实践
    汉字转全拼,简拼组件
    深度复制
    无法删除注册表健值
  • 原文地址:https://www.cnblogs.com/Tiw-Air-OAO/p/12468758.html
Copyright © 2011-2022 走看看