Educational Codeforces Round 40 (Rated for Div. 2) D. Fight Against Traffic(最短路径)

http://codeforces.com/contest/954/problem/D

题意:给你n个点m条路径(无向),再给你一个起点s、一个终点t,此时可以得到s到t的最短距离,让求增加多少条边使得s到t的最短距离不变。

题解:就是求最短路径的题,我们可以先求出起点s到每个点的最短路径ds[],再求t点到每个点的最短距离dt[],我们可以得到s到t的最短距离D=ds[t]=dt[s],然后遍历一遍所有的点(u,v),让他们满足u,v两点直接没有边并且ds[u]+dt[v]+1<=D&&ds[v]+dt[u]+1<=D。

  这道题可以用两种求最短路径的方法求.

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int inff=0x3f3f3f;
 4 const int maxn=1005;
 5 int n,m;
 6 int s,t;
 7 int ds[maxn];/*s点到各个点的最小距离*/
 8 int dt[maxn];
 9 int edge[maxn][maxn];
10 int pos[maxn];
11 void DIJ(int st,int dis[])
12 {
13     for(int i=1; i<=n; i++)
14     {
15         pos[i]=0;
16         dis[i]=inff;
17     }
18     dis[st]=0;
19     for(int i=1; i<=n; i++)
20     {
21         int minj,MM;
22         MM=inff;
23         for(int j=1; j<=n; j++)
24             if(!pos[j]&&dis[j]<=MM)
25             {
26                 MM=dis[j];
27                 minj=j;
28             }
29         pos[minj]=1;
30         for(int j=1; j<=n; j++)
31             dis[j]=min(dis[j],dis[minj]+edge[minj][j]);
32     }
33 }
34 int main()
35 {
36     while(scanf("%d%d%d%d",&n,&m,&s,&t)!=EOF)
37     {
38         memset(edge,inff,sizeof(edge));
39         for(int i=1;i<=m;i++)
40         {
41             int x,y;
42             scanf("%d%d",&x,&y);
43             edge[x][y]=1;
44             edge[y][x]=1;
45         }
46         DIJ(s,ds);
47         DIJ(t,dt);
48         int D=ds[t];
49         int ans=0;
50         for(int u=1;u<=n;u++)
51         {
52             for(int v=1;v<=n;v++)
53             {
54                 if(u==v)
55                     continue;
56                 if(edge[u][v]!=1)
57                 {
58                     if(ds[u]+dt[v]+1>=D&&ds[v]+dt[u]+1>=D)
59                     {
60                         ans++;
61                         edge[u][v]=1;
62                         edge[v][u]=1;
63                     }
64                 }
65             }
66         }
67         printf("%d\n",ans);
68     }
69     return 0;
70 }
DIJ
2018-03-24
11:02:22
 1 #include<bits/stdc++.h>
 2 
 3 using namespace std;
 4 const int inff=0x3f3f3f;
 5 const int maxn=1005;
 6 int n,m;
 7 int s,t;
 8 int ds[maxn];/*s�㵽���������С����*/
 9 int dt[maxn];
10 int edge[maxn][maxn];
11 vector<int>v[maxn];
12 int pos[maxn];
13 
14 void SPAF(int st,int dis[])
15 {
16     for(int i=1;i<=n;i++)
17     {
18         dis[i]=inff;
19         pos[i]=0;
20     }
21     queue<int>q;
22     while(q.size())
23         q.pop();
24     q.push(st);
25     pos[st]=1;
26     dis[st]=0;
27     while(q.size())
28     {
29         st=q.front();
30         q.pop();
31         pos[st]=0;
32         int ss=v[st].size();
33         for(int i=0;i<ss;i++)
34         {
35             int en=v[st][i];
36             if(dis[en]>dis[st]+1)
37             {
38                 dis[en]=dis[st]+1;
39                 if(pos[en]==0)
40                 {
41                     q.push(en);
42                     pos[en]=1;
43                 }
44             }
45         }
46     }
47 }
48 int main()
49 {
50     while(scanf("%d%d%d%d",&n,&m,&s,&t)!=EOF)
51     {
52         memset(edge,0,sizeof(edge));
53         for(int i=1;i<=n;i++)
54             v[i].clear();
55         for(int i=1;i<=m;i++)
56         {
57             int x,y;
58             scanf("%d%d",&x,&y);
59             edge[x][y]=1;
60             edge[y][x]=1;
61             v[x].push_back(y);
62             v[y].push_back(x);
63         }
64         SPAF(s,ds);
65         SPAF(t,dt);
66         int D=ds[t];
67         int ans=0;
68         for(int u=1;u<=n;u++)
69         {
70             for(int v=1;v<=n;v++)
71             {
72                 if(u==v)
73                     continue;
74                 if(edge[u][v]==0)
75                 {
76                     if(ds[u]+dt[v]+1>=D&&ds[v]+dt[u]+1>=D)
77                     {
78                         ans++;
79                         edge[u][v]=1;
80                         edge[v][u]=1;
81                         //printf("u=%d v=%d\n",u,v);
82                     }
83                 }
84             }
85         }
86         printf("%d\n",ans);
87     }
88     return 0;
89 }
SPFA

 

 

 

 

  做这道题的感想!~!~~:

  之所以把这道题记录下来是因为,刚开始的时候我使用的是DIJ求最短距离,结果在对edge[][]数组初始值为0了,让自己在第一组样例一直出错,之后发现是在求最短距离这里出错的,但是就是找不到在哪里错,想了很久才发现这个错误点,edge[][]初始值应该为inf就是两点之间没有直接相连的边是他们的edge为inf.

  当时很久找不出DIJ哪里出错就用的SPFA来做的,AC之后才返回来寻找了一下自己的DIJ出错的地方。

posted @ 2018-03-24 11:03  孟加拉国  阅读(199)  评论(0编辑  收藏  举报