郑大校赛 道路网络

 

题意就是求最短路,唯一不同之处就是,中间有一条路可以之花费一半的代价。

解题方法就是两次求最短路(起点到各点,终点到各点),之后枚举每条边。每条边有两个端点,所以有两种可能。

View Code
 1 #include <iostream>
 2 #include <cstring>
 3 #include <cstdio>
 4 using namespace std;
 5 const int MAX=1005;
 6 const int INF=12345674;
 7 int N,n;
 8 int sdist[MAX],vist[MAX],tdist[MAX];
 9 int map[MAX][MAX];
10 struct  {
11     int x,y,z;
12 }edge[51005];
13 void INIT()
14 {
15     int i,j;
16     for (i=1;i<=n;i++)
17     {
18         vist[i]=0;
19         for (j=1;j<=n;j++)
20         {
21             map[i][j]=INF;
22         }
23         map[i][i]=0;
24         sdist[i]=INF;
25     }
26     N=0;
27 }
28 int max(int x,int y)
29 {
30     if(x>y)return x;
31     else return y;
32 }
33 
34 void Dijs(int s)
35 {
36     int i,j,v,ma;
37     for (i=1;i<=n;i++)
38         sdist[i]=map[s][i];
39     
40     vist[s]=1;
41     sdist[s]=0;
42     v=s;
43     for (i=1;i<n;i++)
44     {
45         ma=INF;
46         for (j=1;j<=n;j++)
47             if(!vist[j]&&sdist[j]<ma){
48                 ma=sdist[j];
49                 v=j;
50             }
51             if(ma>=INF)break;
52             vist[v]=1;
53             for (j=1;j<=n;j++)
54                 if(!vist[j]&&(map[v][j]+sdist[v])<sdist[j]){
55                     sdist[j]=map[v][j]+sdist[v];
56                 }
57     }
58 }    
59 int main()
60 {
61  int i,k,m,s,t,x,y,z,sum;
62     scanf("%d",&k);
63     while (k--)
64     {
65         scanf("%d%d",&n,&m);
66         INIT();
67         for (i=1;i<=m;i++)
68         {
69             scanf("%d%d%d",&x,&y,&z);
70             if(map[x][y]>z){
71                 map[x][y]=map[y][x]=z;
72                 edge[++N].x=x;
73                 edge[N].y=y;
74                 edge[N].z=z;
75             }
76         }
77             scanf("%d%d",&s,&t);
78             Dijs(s);
79             sum=INF;
80             if(sdist[t]<INF){
81                 for (i=1;i<=n;i++)
82                     tdist[i]=sdist[i];
83 
84                 memset(vist,0,sizeof(vist));
85                 Dijs(t);
86                 for (i=1;i<=N;i++)
87                 {
88                     t=(sdist[edge[i].x]+tdist[edge[i].y]+edge[i].z/2);
89                     t=min(t,(sdist[edge[i].y]+tdist[edge[i].x]+edge[i].z/2));
90                     if(t<sum)sum=t;
91                 }
92                 printf("%d\n",sum);
93             }
94             else printf("The budget is wrong\n");
95     }    
96     return 0;
97 }

 

posted @ 2012-04-25 17:30  我们一直在努力  阅读(189)  评论(0编辑  收藏  举报