CodeForces

题目大意:

  有一个有向无环图,n个点m条边,所有边权为1或2,求一组使所有从1到n的路径长度相同的边权的方案。

思路:

  设从1到i的最短路为dist[i],若有一条从x到y的边,则1<=dist[y]-dist[x]<=2,即dist[y]-dist[x]>=1且dist[x]-dist[y]>=-2,有了这个约束条件,就可以跑差分约束了。不过跑之前要先把从1到n的路径上的点找出来,否则会使无用的点对结果产生影响。

代码:

 1 #include<queue>
 2 #include<vector>
 3 #include<cstdio>
 4 using namespace std;
 5 const int N=1009,M=5009;
 6 int cnt,n,m,i,x,y,h,t,a[M],b[M],v[M<<1],pre[N],last[M<<1],w[M<<1],head[N],dist[N],count[N];
 7 bool vis[N],mark[N],flag[N];
 8 vector <int> l[N],r[N];
 9 
10 int read()
11 {
12     int x=0;
13     char ch=getchar();
14     while (ch<'0' || ch>'9') ch=getchar();
15     while (ch>='0' && ch<='9') x=(x<<1)+(x<<3)+ch-48,ch=getchar();
16     return x;
17 }
18 
19 void add(int x,int y,int z)
20 {
21     v[++cnt]=y,last[cnt]=head[x],head[x]=cnt,w[cnt]=z;
22 }
23 
24 bool SPFA()
25 {
26     queue <int> q;
27     for (q.push(1),vis[1]=count[1]=1;!q.empty();)
28         for (x=q.front(),q.pop(),vis[x]=0,i=head[x];i;i=last[i])
29             if (dist[y=v[i]]<w[i]+dist[x])
30             {
31                 dist[y]=dist[x]+w[i];
32                 if (!vis[y])
33                 {
34                     q.push(y),vis[y]=1;
35                     if (++count[y]>n) return 1;
36                 }
37             }
38     return 0;
39 }
40 
41 void wk1(int x)
42 {
43     int i;
44     for (flag[x]=1,i=0;i<l[x].size();i++)
45         if (!flag[l[x][i]]) wk1(l[x][i]);
46 }
47 
48 void wk2(int x)
49 {
50     int i;
51     for (mark[x]=1,i=0;i<r[x].size();i++)
52         if (!mark[r[x][i]]) wk2(r[x][i]);
53 }
54 
55 int main()
56 {
57     for (n=read(),m=read(),i=1;i<=m;i++) a[i]=read(),b[i]=read();
58     for (i=1;i<=m;i++) l[a[i]].push_back(b[i]),r[b[i]].push_back(a[i]);
59     for (wk1(1),wk2(n),i=1;i<=n;i++) flag[i]&=mark[i];
60     for (i=1;i<=m;i++)
61         if (flag[a[i]] && flag[b[i]]) add(a[i],b[i],1),add(b[i],a[i],-2);
62     if (SPFA()) puts("No");
63     else
64         for (puts("Yes"),i=1;i<=m;i++)
65             if (flag[a[i]] && flag[b[i]]) printf("%d
",dist[b[i]]-dist[a[i]]);
66             else puts("1");
67     return 0;
68 }
我一直在繁华的苍凉中徘徊着,用一颗OI的心寻找着生命和宇宙的美妙与玄奥。
原文地址:https://www.cnblogs.com/HHshy/p/5822143.html