codeforces 241 E Flights
2016-07-12 16:57
204 查看
题目大意
一个有向图,规定每条边的边权只能为1或2,要求给出一种方案,使得每条1到n的路径长度都一样。题解
差分约束系统。如果一条边不在1到n的路径上,那么就不用考虑它。
于是可以建出一个新图。
对于一条边(a,b),则有
dis(b)−dis(a)⩽2
dis(a)−dib(b)⩽−1
然后跑一边SPFA,判掉负圈,有就是无解。
然后遍历所有的边,注意,只有在1~n的路径上的边,边权大于2或小于1时,才是无解,其他的边可以任意赋值,因为它们对答案无影响。
至于如何构图,我一开始是想dp一下,记录每个点是否可以到n。
我用-1表示未访问,1表示可以,0表示不可以
由于一些点不一定可以到达,所以这些点的dp值始终是-1,然而我在判断是不是在新图中时用的是dp[i]!=0,于是挂掉了,WA了好几次。
当然还可以两边dfs,从起点dfs一遍,终点在反向图上dfs一遍,两个点都可以到达的点才是新图上的点。
贴代码:
两边dfs:
#include <cstdio> #include <queue> #include <algorithm> using namespace std; const int M=1005; struct Edge{ int to,v,nxt; Edge(int _to=0,int _v=0,int _nxt=0):to(_to),v(_v),nxt(_nxt){} }edge[M*10]; int etot,n,m,a[M*10],b[M*10]; queue<int>Q; int cnt[M],dis[M],head[M]; bool mark[M],flag[M]; void add_edge(int a,int b,int c){ edge[etot]=Edge(b,c,head[a]); head[a]=etot++; } int on_the_road[M]; bool SPFA(){ for(int i=2;i<=n;i++) dis[i]=2000000000; Q.push(1); while(!Q.empty()){ int x=Q.front(); Q.pop(); mark[x]=0; for(int i=head[x];~i;i=edge[i].nxt){ int to=edge[i].to; if(on_the_road[to]!=2) continue; if(dis[to]>dis[x]+edge[i].v){ dis[to]=dis[x]+edge[i].v; if(++cnt[to]>n) return false; if(!mark[to]){ mark[to]=1; Q.push(to); } } } } return true; } void dfs(int x,bool f){ if(flag[x]) return; flag[x]=1; on_the_road[x]++; for(int i=head[x];~i;i=edge[i].nxt) if((f==1)^(edge[i].v>0)) dfs(edge[i].to,f); } int main(){ scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) head[i]=-1; for(int i=1;i<=m;i++){ scanf("%d%d",&a[i],&b[i]); add_edge(a[i],b[i],2); add_edge(b[i],a[i],-1); } dfs(1,0); for(int i=1;i<=n;i++) flag[i]=0; dfs(n,1); if(!SPFA()) puts("No"); else{ for(int j=1;j<=m;j++){ if(on_the_road[b[j]]==2&&on_the_road[a[j]]==2&&(dis[b[j]]-dis[a[j]]<=0||dis[b[j]]-dis[a[j]]>2)){ puts("No"); return 0; } } puts("Yes"); for(int i=1;i<=m;i++){ if(dis[b[i]]-dis[a[i]]<1||dis[b[i]]-dis[a[i]]>2) puts("1"); else printf("%d\n",dis[b[i]]-dis[a[i]]); } } return 0; }
dp
#include <cstdio> #include <queue> #include <algorithm> using namespace std; const int M=1005; struct Edge{ int to,v,nxt; Edge(int _to=0,int _v=0,int _nxt=0):to(_to),v(_v),nxt(_nxt){} }edge[M*10]; int etot,n,m,a[M*10],b[M*10]; queue<int>Q; int cnt[M],dis[M],head[M]; bool mark[M]; void add_edge(int a,int b,int c){ edge[etot]=Edge(b,c,head[a]); head[a]=etot++; } int on_the_road[M]; bool SPFA(){ for(int i=2;i<=n;i++) dis[i]=2000000000; Q.push(1); while(!Q.empty()){ int x=Q.front(); Q.pop(); mark[x]=0; for(int i=head[x];~i;i=edge[i].nxt){ int to=edge[i].to; if(!on_the_road[to]||on_the_road[to]==-1) continue; if(dis[to]>dis[x]+edge[i].v){ dis[to]=dis[x]+edge[i].v; if(++cnt[to]>n) return false; if(!mark[to]){ mark[to]=1; Q.push(to); } } } } return true; } int dfs(int x){ if(on_the_road[x]!=-1) return on_the_road[x]; on_the_road[x]=0; for(int i=head[x];~i;i=edge[i].nxt) if(edge[i].v>0&&dfs(edge[i].to)) on_the_road[x]=1; if(x==n) on_the_road[x]=1; return on_the_road[x]; } int main(){ scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) on_the_road[i]=head[i]=-1; for(int i=1;i<=m;i++){ scanf("%d%d",&a[i],&b[i]); add_edge(a[i],b[i],2); add_edge(b[i],a[i],-1); } dfs(1); if(!SPFA()) puts("No"); else{ for(int j=1;j<=m;j++){ if(on_the_road[b[j]]>0&&on_the_road[a[j]]>0&&(dis[b[j]]-dis[a[j]]<=0||dis[b[j]]-dis[a[j]]>2)){ puts("No"); return 0; } } puts("Yes"); for(int i=1;i<=m;i++){ if(dis[b[i]]-dis[a[i]]<1||dis[b[i]]-dis[a[i]]>2) puts("1"); else printf("%d\n",dis[b[i]]-dis[a[i]]); } } return 0; }
相关文章推荐
- Codeforces Round #197 (Div. 2)
- Codeforces Round #198 (Div. 1)
- Codeforces 405E Codeforces Round #238 (Div. 2)E
- Codeforces 407C Codeforces Round #239 (Div. 1)C
- CodeForces 449A - Jzzhu and Chocolate
- CodeForces 449 B. Jzzhu and Cities
- codeforces 618C. Constellation
- Codeforces Round #349 (Div. 2) - C
- Codeforces Round #265 (Div. 2)
- Codeforces #310 div2 C. Case of Matryoshkas
- 状态压缩DP codeforces 244 Problem C. The Brand New Function 和 codeforces 165 E. Compatible Numbers
- codeforces 16 Problem E fish
- Codeforces Round332 部分题解
- CodeForces 603A_Alternative Thinking (DP)
- CodeForces 602B_Approximating a Constant Range_DP
- Codeforces round #247 for Div. 2
- Codeforces Round #246 (Div. 2)
- Codeforces #264(div 2)D.Gargari and Permutations
- Codeforces Round #236 (Div. 2)------A,B
- codeforces 257 div2 B