CF 241E flights 最短路,重复迭代直到稳定 难度:3

http://codeforces.com/problemset/problem/241/E

首先检测哪些点会出现在从起点到终点的路上,可以用dfs或者迭代,

然后,对于所有的边,设f为边起点,t为边终点,dp[i]为从起点出发到i点所必须花费的时间,则当dp[t]>dp[f]+2,也就是超出限制时,把dp[t]限制到dp[f]+2处,对于dp[f]>dp[t]+1,限制dp[f]到dp[t]+1处

因为这个图没有圈,所以如果存在满足题意的边权方案,那么每次使得一个点的dp值满足要求,n次之后一定全部满足要求,不再发生改动,如果不存在满足题意的边权方案,就会不断发生震荡,此时及时停止循环输出No即可

注意不在起点到终点路上的边全都为1

 1 #include <cstdio>
 2 #include <cstring>
 3 using namespace std;
 4 const int maxn=1e3+2;
 5 const int maxm=5e3+2;
 6 const int inf=0x3fffffff;
 7 int n,m;
 8 int vis[maxn];
 9 int e[maxm][2];
10 int dp[maxn];
11 int main(){
12         scanf("%d%d",&n,&m);
13         for(int i=0;i<m;i++)scanf("%d%d",e[i],e[i]+1);
14         vis[1]=1;vis[n]=2;
15         bool fl=true;
16         while(fl){
17                 fl=false;
18                 for(int i=0;i<m;i++){
19                         int f=e[i][0],t=e[i][1];
20                         if((vis[f]&1)&&(vis[t]&1)==0){
21                                 vis[t]|=1;fl=true;
22                         }
23                         if((vis[t]&2)&&(vis[f]&2)==0){
24                                 vis[f]|=2;fl=true;
25                         }
26                 }
27         }
28         fl=true;
29         int cnt=0;
30         while(fl){
31                 fl=false;
32                 cnt++;
33                 for(int i=0;i<m;i++){
34                         int f=e[i][0],t=e[i][1];
35                         if(vis[f]==3&&vis[t]==3){
36                                 if(dp[t]>dp[f]+2){
37                                         dp[t]=dp[f]+2;
38                                         fl=true;
39                                 }
40                                 if(dp[f]>dp[t]-1){
41                                         dp[f]=dp[t]-1;
42                                         fl=true;
43                                 }
44                         }
45                 }
46                 if(cnt>n&&fl){puts("No");return 0;}
47         }
48         puts("Yes");
49         for(int i=0;i<m;i++){
50                 int f=e[i][0],t=e[i][1];
51                 if(vis[f]==3&&vis[t]==3)printf("%d
",dp[t]-dp[f]);
52                 else puts("1");
53         }
54         return 0;
55 }
原文地址:https://www.cnblogs.com/xuesu/p/4341831.html