Codeforces 241E:Flights

来源:互联网 发布:汽车管理系统源码 编辑:程序博客网 时间:2024/05/19 12:38

【大意】
有一个n 个结点且每条边权值均为1 的有向图,要你把一些边权改成2 使得任意一条从1到n 的路径长度都相等。
【解答】
相当于给定了一个有向图,现在让你给每条边确定一个权值。
权值的值域为1或者2,每条1到n的路径都是最短路。
disxxn的最短路,对于每一条边E(u,v)
都有

disv+1disudisv+2

按照这个不等式建立差分约束,注意把1不能到达的点和不能到达n的点删去。
因为数据范围很小,最短路可以使用Bellman_Ford换取更短的代码长度

#include <bits/stdc++.h>#define N 5050using namespace std;#define U e[_][0]#define V e[_][1]int dis[N],e[N][2],vis[N],vv[N][2];int n,m;inline int rd() {int r;scanf("%d",&r);return r;}void dfs(int u,int t) {    vv[u][t] = 1;    for (int _=1;_<=m;_++) if (e[_][t]==u && !vv[ e[_][t^1] ][t]) dfs( e[_][t^1], t );}int main() {    n = rd(), m = rd();    for (int _=1;_<=m;_++) U = rd(), V = rd();    dfs(1,0), dfs(n,1);    for (int _=1;_<=n;_++) vv[_][0] && vv[_][1] ? vis[_] = 1 :0;    for (int _=1;_<=n;_++)        for (int i=1;i<=m;i++) if (vis[e[i][0]] && vis[e[i][1]]) {            int u = e[i][0], v = e[i][1];            dis[u] = min(dis[v]+2, dis[u]);            dis[v] = min(dis[u]-1, dis[v]);        }    for (int _=1;_<=m;_++) if (vis[U] && vis[V]){        int x = dis[U] - dis[V];        if (x!=1 && x!=2) return puts("No"), 0;    }    puts("Yes");    for (int _=1;_<=m;_++) printf("%d\n",max(min( dis[U]-dis[V],2 ), 1));    return 0;}
原创粉丝点击