https://codeforces.com/problemset/problem/241/E
这2600分的题就。。。完全想不到可以用差分约束做
我们可以知道,从1到n的所有路径大小相等,那只和1到n的所有路径构成的子图这些点有关。
那么由于1到n的路径大小相同,那么1到这个子图的所有点的路径都是相等的
也就是我们保证从1开始走的所有dis[i]都相等,就可以用差分约束了。。。。
最后判断每一条两个点都是子图里的边,他们的dis差值是否>=2就是2,否则就是1.
#include<bits/stdc++.h>
using namespace std;
const int maxl=5e3+10;
int n,m,ans,cnt;
int a[maxl],b[maxl],c[maxl];
int dis[maxl],ehead[maxl],num[maxl];
vector<int> pe[maxl],fe[maxl];
struct ed
{
int to,nxt,l;
}e[maxl*4];
queue<int> q;
bool in[maxl];
inline void dfs1(int u)
{
c[u]=1;
for(int v : pe[u])
{
if(c[v]) continue;
dfs1(v);
}
}
inline void dfs2(int u)
{
c[u]+=2;
for(int v : fe[u])
{
if(c[v]>1) continue;
dfs2(v);
}
}
inline void add(int u,int v,int l)
{
e[++cnt].to=v;e[cnt].l=l;
e[cnt].nxt=ehead[u];ehead[u]=cnt;
}
inline void prework()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++)
{
scanf("%d%d",&a[i],&b[i]);
pe[a[i]].push_back(b[i]);
fe[b[i]].push_back(a[i]);
}
dfs1(1);dfs2(n);
for(int i=1;i<=m;i++)
if(c[a[i]]==3 && c[b[i]]==3)
{
add(a[i],b[i],1);
add(b[i],a[i],-2);
}
}
inline void mainwork()
{
int u,v;ans=1;
dis[1]=0;in[1]=true;q.push(1);num[1]=1;
while(!q.empty())
{
u=q.front();q.pop();
for(int i=ehead[u];i;i=e[i].nxt)
{
v=e[i].to;
if(dis[u]+e[i].l>dis[v])
{
dis[v]=dis[u]+e[i].l;
if(!in[v])
{
in[v]=true;num[v]++;
q.push(v);
if(num[v]>=n)
{
ans=0;
return;
}
}
}
}
in[u]=false;
}
}
inline void print()
{
if(ans==0)
puts("No");
else
{
puts("Yes");
for(int i=1;i<=m;i++)
if(dis[b[i]]-dis[a[i]]>=2)
puts("2");
else
puts("1");
}
}
int main()
{
prework();
mainwork();
print();
return 0;
}