• 21.11.16模拟 学校


    题意就是求出去掉一条边,还能按照原来的最短路的耗时从s到t

    先一遍Dij求出s~t的最短路,然后从t bfs倒推回去,建立出最短路图C,然后在C上求割边
    去掉的边若是C上的割边,那么就不能到达,否则能到达

    const int N = 4e4 + 79;
    const int M = 2e5 + 79;
    struct graph {
    	int head[N], tot = 1, next[M << 1], ver[M << 1], edge[M << 1], num[M << 1];
    	inline void add(int id, int a, int b, int c) {
    		ver[++tot] = b;
    		num[tot] = id;
    		next[tot] = head[a];
    		head[a] = tot;
    		edge[tot] = c;
    	}
    } G, C;
    int n, m, s, t;
    int d[N];
    bool vis[N];
    #define pii std::pair<int,int>
    std::priority_queue<pii, std::vector<pii>, std::greater<pii> >Q;
    inline void Dijkstra() {
    	memset(d, 0x3f, sizeof d);
    	d[s] = 0;
    	Q.push({0, s});
    	while(Q.size()) {
    		int x(Q.top().second);
    		Q.pop();
    		if(vis[x]) continue;
    		vis[x] = 1;
    		repg(x) {
    			int y(G.ver[i]), z(G.edge[i]);
    			if(d[y] > d[x] + z) {
    				d[y] = d[x] + z;
    				Q.push({d[y], y});
    			}
    		}
    	}
    }
    int low[N], dfn[N], tim;
    bool bridge[M << 1];
    inline void tarjan(int x, int in_edge) {
    	low[x] = dfn[x] = ++tim;
    	repc(x) {
    		int y(C.ver[i]);
    		if(!dfn[y]) {
    			tarjan(y, i);
    			low[x] = min(low[x], low[y]);
    
    			if(low[y] > dfn[x]) {
    				bridge[C.num[i]] = 1;
    			}
    		} else if(C.num[i] != C.num[in_edge]) {
    			low[x] = min(low[x], dfn[y]);
    		}
    	}
    }
    
    
    int q[N];
    inline void init() {
    	memset(vis, 0, sizeof vis);
    	vis[t] = 1;
    	q[++q[0]] = t;
    	rep(_, 1, q[0]) {
    		int x(q[_]);
    		repg(x) {
    			int y(G.ver[i]), z(G.edge[i]);
    			if(d[y]+z == d[x] ) {
    
    				C.add(G.num[i], x, y, z);
    				C.add(G.num[i], y, x, z);
    				if(!vis[y]) {
    					vis[y] = 1;
    					q[++q[0]] = y;
    				}
    			}
    		}
    	}
    	tarjan(s, -1);
    }
    
    int main() {
    	freopen("school.in","r",stdin);
    	freopen("school.out","w",stdout);
    	read(n);
    	read(m);
    	read(s);
    	read(t);
    	int a, b, c;
    	rep(i, 1, m) {
    		read(a);
    		read(b);
    		read(c);
    		G.add(i, a, b, c);
    		G.add(i, b, a, c);
    	}
    	Dijkstra();
    	init();
    	int Q, x;
    	read(Q);
    	while(Q--) {
    		read(x);
    		puts(bridge[x] ? "No" : "Yes");
    	}
    	return 0;
    }
    

    本文来自博客园,作者:{2519},转载请注明原文链接:https://www.cnblogs.com/QQ2519/p/15566296.html

  • 相关阅读:
    hibernate各种状态
    Persistence createEntityManagerFactory方法使用
    JS数组学习笔记
    ES6笔记之参数默认值(译)
    JS是按值传递还是按引用传递?
    linux awk命令详解
    Linux Shell笔记之sed
    类似微信红包随机分配js方法
    ionic tabs隐藏完美解决
    mustache 获取json数据内数组对象指定元素的方法
  • 原文地址:https://www.cnblogs.com/QQ2519/p/15566296.html
Copyright © 2020-2023  润新知