zoukankan      html  css  js  c++  java
  • [CF241E]Flights

    [CF241E]Flights

    题目大意:

    给一张(n(nle1000))个点(m(mle5000))条边的DAG,确定每条边的边权(w_i(w_iin{1,2})),使得所有从(1)(n)的路径拥有相同的长度。

    思路:

    首先用BFS求出所有与(1)(n)路径有关的点构成的子图。

    这样,(1)到子图上每个点的长度都是确定的,即终点相同的路径拥有相同的长度。有(d_i)表示点(1)到点(i)的距离,则对于边(u o v),有(1le d_v-d_ule2)。这样我们就可以得到一个差分约束系统,使用SPFA求最长路即可。

    源代码:

    #include<queue>
    #include<cstdio>
    #include<cctype>
    #include<vector>
    inline int getint() {
    	register char ch;
    	while(!isdigit(ch=getchar()));
    	register int x=ch^'0';
    	while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
    	return x;
    }
    const int N=1001,M=5000;
    struct Edge {
    	int u,v;
    };
    Edge edge[M];
    std::vector<int> e[N];
    std::vector<Edge> h[N];
    int n,m,vis[N],dis[N];
    bool f[N],g[N],inq[N];
    std::queue<int> q;
    inline void bfs1() {
    	for(register int i=0;i<m;i++) {
    		e[edge[i].u].push_back(edge[i].v);
    	}
    	q.push(1);
    	f[1]=true;
    	while(!q.empty()) {
    		const int &x=q.front();
    		for(auto &y:e[x]) {
    			if(!f[y]) {
    				q.push(y);
    				f[y]=true;
    			}
    		}
    		q.pop();
    	}
    	for(register int i=1;i<=n;i++) {
    		e[i].clear();
    	}
    }
    inline void bfs2() {
    	for(register int i=0;i<m;i++) {
    		e[edge[i].v].push_back(edge[i].u);
    	}
    	q.push(n);
    	g[n]=true;
    	while(!q.empty()) {
    		const int &x=q.front();
    		for(auto &y:e[x]) {
    			if(!g[y]) {
    				q.push(y);
    				g[y]=true;
    			}
    		}
    		q.pop();
    	}
    	for(register int i=1;i<=n;i++) {
    		e[i].clear();
    	}
    }
    inline void spfa() {
    	q.push(1);
    	while(!q.empty()) {
    		const int &x=q.front();
    		for(auto &j:h[x]) {
    			const int &y=j.u,&w=j.v;
    			if(dis[x]+w>dis[y]) {
    				dis[y]=dis[x]+w;
    				if(!inq[y]) {
    					inq[y]=true;
    					q.push(y);
    					if(++vis[y]>n) {
    						throw 0;
    					}
    				}
    			}
    		}
    		q.pop();
    		inq[x]=false;
    	}
    }
    int main() {
    	n=getint(),m=getint();
    	for(register int i=0;i<m;i++) {
    		const int u=getint(),v=getint();
    		edge[i]=(Edge){u,v};
    	}
    	bfs1();
    	bfs2();
    	for(register int i=0;i<m;i++) {
    		const int &u=edge[i].u,&v=edge[i].v;
    		if(f[u]&&g[u]&&f[v]&&g[v]) {
    			h[u].push_back((Edge){v,1});
    			h[v].push_back((Edge){u,-2});
    		}
    	}
    	try {
    		spfa();
    	} catch(...) {
    		puts("No");
    		return 0;
    	}
    	puts("Yes");
    	for(register int i=0;i<m;i++) {
    		const int &u=edge[i].u,&v=edge[i].v;
    		if(f[u]&&g[u]&&f[v]&&g[v]) {
    			printf("%d
    ",dis[v]-dis[u]);
    		} else {
    			puts("1");
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    Magisk+Xposed+Root switch+Pokémon GO
    [数据库连接池] Java数据库连接池--DBCP浅析.
    [C#反射]C#中的反射解析及使用.
    [Java工具]Java常用在线工具集合.
    [Java拾遗五]使用Session防止表单重复提交
    [Java拾遗四]JavaWeb基础之Servlet_Request&&Response
    [Java拾遗三]JavaWeb基础之Servlet
    [Java拾遗二]Tomact及Http 部分总结.
    [Java拾遗一] XML的书写规范与解析.
    [数据库操作]Java中的JDBC的使用方法.
  • 原文地址:https://www.cnblogs.com/skylee03/p/9718275.html
Copyright © 2011-2022 走看看