CF241E Flights 题解
作者:互联网
CF241E
简要题意
\(n\) 个点,\(m\) 条有向边,每条边初始边权是 \(1\),让将一些边的边权变为 \(2\),使所有从点 \(1\) 到 \(n\) 的路径长度相等。
分析
首先发现如果一条边不在 \(1\) 到 \(n\) 的任意一条路径上,可以给它任意赋边权,因此只需考虑在 \(1\) 到 \(n\) 路径上的边。设 \(1\) 到 \(i\) 的最短路径长为 \(d_i\),由于所有 \(1\) 到 \(n\) 的路径都等长,于是有 \(\forall (u,v),d_u=d_v+w\),其中 \(w\) 为 \((u,v)\) 的边权。于是题目中对边权的限制可以转换为对 \(d\) 的限制,即:
\[\begin{cases} d_u-d_v\leq2 \\ 1\leq d_u-d_v \end{cases} \Longrightarrow \begin{cases} d_u\leq d_v+2\\ d_v\leq d_u+1 \end{cases} \],发现这是个典型的差分约束的形式,于是跑个 SPFA 就行了。最后 \((u,v)\) 的边权就是 \(d_v-d_u\)。
核心代码
int n,m,head[MAXN];vector<Pair>e;bitset<MAXN>v1,v2;
struct Edge{
int to,dis,nxt;
Edge(){;}Edge(int _to,int _dis,int _nxt):to(_to),dis(_dis),nxt(_nxt){}
};vector<Edge>edge;
void add_edge(int u,int v,int w){edge.push_back(Edge{v,w,head[u]});head[u]=edge.size()-1;}
int dis[MAXN],cnt[MAXN];bitset<MAXN>vis;queue<int>q;
bool spfa(int s){
vis.reset();mem(dis,0x3f);mem(cnt,0);vis[s]=true;cnt[s]=1;dis[s]=0;q.push(s);
while(!q.empty()){
int u=q.front();q.pop();
for(int i=head[u];i!=-1;i=edge[i].nxt){
int v=edge[i].to,w=edge[i].dis;vis[u]=false;
if(dis[v]>dis[u]+w){
dis[v]=dis[u]+w;
if(!vis[v]) vis[v]=true,cnt[v]++,q.push(v);
if(cnt[v]>=n) return false;
}
}
}return true;
}vector<int>ed[MAXN];
void dfs(int u){
for(auto v:ed[u]) if(!v1[v]) v1[v]=true,dfs(v);
}void dfs1(int u){
for(auto v:ed[u]) if(!v2[v]) v2[v]=true,dfs1(v);
}
signed main(){
qread(n,m);int i,j;mem(head,-1);
for(i=1;i<=m;i++){
int u,v;qread(u,v);e.push_back(Pair(u,v));
}for(auto i:e) ed[i.first].push_back(i.second);
dfs(1);for(i=1;i<=n;i++) ed[i].clear();
for(auto i:e) ed[i.second].push_back(i.first);dfs1(n);
if(!v1[n]) return printf("No\n"),0;v1[1]=v1[n]=v2[1]=v2[n]=true;
for(auto i:e){
if(v1[i.first]&&v1[i.second]&&v2[i.first]&&v2[i.second])
add_edge(i.first,i.second,2),add_edge(i.second,i.first,-1);
}
if(!spfa(1)) return printf("No\n"),0;puts("Yes");
for(auto i:e){
if(v1[i.first]&&v1[i.second]&&v2[i.first]&&v2[i.second])
printf("%lld\n",dis[i.second]-dis[i.first]);
else printf("1\n",i.first,i.second);
}
#ifndef ONLINE_JUDGE
system("pause > null");
#endif
return 0;
}
标签:cnt,int,题解,head,vis,Flights,edge,CF241E,dis 来源: https://www.cnblogs.com/lxy-2022/p/CF241E-Solution.html