郑大校赛 道路网络
题意就是求最短路,唯一不同之处就是,中间有一条路可以之花费一半的代价。
解题方法就是两次求最短路(起点到各点,终点到各点),之后枚举每条边。每条边有两个端点,所以有两种可能。
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 }