CF
有\(n\)個點\(m\)條邊,要求給每條邊賦一個\(1\)或\(2\)的邊權,判斷可否使得每一條\(1\)到\(n\)的路徑的權值和都相等,若是能夠給出一個方案。ios
首先有這樣一個結論:從\(1\)號點到達任意一個點的全部路徑的權值都相同。比較顯然,就不證實了。
而後就能夠直接差分約束了?spa
#include<iostream> #include<cstdio> #include<cstring> #include<vector> #include<queue> using namespace std; #define MAX 1010 inline int read() { int x=0;bool t=false;char ch=getchar(); while((ch<'0'||ch>'9')&&ch!='-')ch=getchar(); if(ch=='-')t=true,ch=getchar(); while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar(); return t?-x:x; } struct Line{int v,next,w;}e[MAX*10]; int h[MAX],cnt=1; inline void Add(int u,int v,int w){e[cnt]=(Line){v,h[u],w};h[u]=cnt++;} vector<int> E1[MAX],E2[MAX]; int n,m,U[MAX*5],V[MAX*5],vis[MAX],dis[MAX],num[MAX];bool inq[MAX]; queue<int> Q; void dfs1(int u){vis[u]|=1;for(int v:E1[u])if(!(vis[v]&1))dfs1(v);} void dfs2(int u){vis[u]|=2;for(int v:E2[u])if(!(vis[v]&2))dfs2(v);} int main() { n=read();m=read(); for(int i=1;i<=m;++i) { int u=read(),v=read();U[i]=u;V[i]=v; E1[u].push_back(v);E2[v].push_back(u); } dfs1(1);dfs2(n); for(int i=1;i<=m;++i) if(vis[U[i]]==3&&vis[V[i]]==3) { Add(U[i],V[i],1); Add(V[i],U[i],-2); } memset(dis,-63,sizeof(dis)); Q.push(1);inq[1]=true;dis[1]=0; while(!Q.empty()) { int u=Q.front();Q.pop(); for(int i=h[u];i;i=e[i].next) { int v=e[i].v; if(dis[v]<dis[u]+e[i].w) { dis[v]=dis[u]+e[i].w; if(!inq[v])inq[v]=true,Q.push(v),++num[v]; } } if(num[u]>=n){puts("No");return 0;} inq[u]=false; } puts("Yes"); for(int i=1;i<=m;++i) if(vis[U[i]]==3&&vis[V[i]]==3)printf("%d\n",dis[V[i]]-dis[U[i]]); else puts("1"); return 0; }