CF241E Flights 题解
作者:互联网
Link.
Description.
有 \(n\) 个点,\(m\) 条边,每条边权为 \(1\) 或 \(2\)。
要求构造一种方案,使得 \(1\) 到 \(n\) 的所有路径长度都相等。
Solution.
差分约束。
首先,\(1\) 到 \(n\) 所有路径长度都相等,那 \(1\) 到所有点长度都相等。
所以相当于每个点有个唯一确定的 \(dis_i\)。
肯定满足 \(\forall (i,j)\in G,1\le dis_j-dis_i\le 2\)。
然后直接差分约束就做完了???
注意还需要找到所有在 \(1\cdots n\) 路径上的边。
Coding.
点击查看代码
//是啊,你就是那只鬼了,所以被你碰到以后,就轮到我变成鬼了{{{
#include<bits/stdc++.h>
using namespace std;typedef long long ll;
template<typename T>inline void read(T &x)
{
x=0;char c=getchar(),f=0;
for(;c<48||c>57;c=getchar()) if(!(c^45)) f=1;
for(;c>=48&&c<=57;c=getchar()) x=(x<<1)+(x<<3)+(c^48);
f?x=-x:x;
}
template<typename T,typename...L>inline void read(T &x,L&...l) {read(x),read(l...);}//}}}
int n,m,ds[1005],ff[5005],tt[5005];char vs[1005],fg[1005];
vector<int>e1[1005];int fr[10005],tw[10005],we[10005],et;
inline char dfs(int x)
{
if(vs[x]) return fg[x];else vs[x]=1;
for(int y:e1[x]) fg[x]|=dfs(y);
return fg[x];
}
int main()
{
read(n,m);for(int i=1,x,y;i<=m;i++) read(x,y),e1[x].push_back(y),ff[i]=x,tt[i]=y;
vs[n]=fg[n]=1,dfs(1),memset(ds,0x3f,sizeof(ds)),ds[1]=0;
for(int i=1;i<=n;i++) if(fg[i]) for(auto j:e1[i])
if(fg[j]) fr[++et]=i,tw[et]=j,we[et]=2,fr[++et]=j,tw[et]=i,we[et]=-1;
for(int i=1;i<=n;i++) for(int j=1;j<=et;j++) ds[tw[j]]=min(ds[fr[j]]+we[j],ds[tw[j]]);
for(int i=1;i<=et;i++) if(ds[tw[i]]>ds[fr[i]]+we[i]) return puts("No"),0;
puts("Yes");for(int i=1;i<=m;i++) if(fg[ff[i]]&&fg[tt[i]]) printf("%d\n",ds[tt[i]]-ds[ff[i]]);else puts("1");
return 0;
}
标签:return,int,题解,read,Flights,fg,1005,CF241E,dis 来源: https://www.cnblogs.com/pealfrog/p/15375748.html