poj 3767(带限制的最短路)
将所有的点按所属的party分为1 2.然后分别求出源点 跟终点到各自的图中的最短路。枚举得出答案。
View Code
1 // File Name: 3767.cpp 2 // Author: Missa 3 // Created Time: 2013/2/7 星期四 20:40:32 4 5 #include<iostream> 6 #include<cstdio> 7 #include<cstring> 8 #include<algorithm> 9 #include<cmath> 10 #include<queue> 11 #include<stack> 12 #include<string> 13 #include<vector> 14 #include<cstdlib> 15 #include<map> 16 using namespace std; 17 18 const int inf = 700000000; 19 const int maxn = 6e2+5; 20 int n,m; 21 int src; 22 int a[maxn][maxn]; 23 int dis[2][maxn]; 24 int part[maxn]; 25 void init() 26 { 27 for(int i=1;i<=n;i++) 28 for(int j=1;j<=n;j++) 29 { 30 if(i==j) 31 a[i][j]=a[j][i]=0; 32 else 33 a[i][j]=a[j][i]=inf; 34 } 35 } 36 void dij()//选择 37 { 38 bool vis[maxn]; 39 memset(vis,0,sizeof(vis)); 40 for(int i=1;i<=n;i++) 41 dis[src-1][i]=inf; 42 for(int i=1;i<=n;i++) 43 if(part[src]==part[i]) 44 dis[src-1][i]=a[src][i]; 45 vis[src]=1; 46 for(int i=1;i<n;i++) 47 { 48 int tmp=inf,k=src; 49 for(int j=1;j<=n;j++) 50 { 51 if(vis[j])continue; 52 if(tmp>dis[src-1][j]) 53 { 54 tmp=dis[src-1][j]; 55 k=j; 56 } 57 } 58 vis[k]=1; 59 for(int j=1;j<=n;j++) 60 { 61 if(vis[j]) continue; 62 if(part[j]==part[src]) 63 dis[src-1][j]=min(dis[src-1][j],dis[src-1][k]+a[k][j]); 64 } 65 } 66 } 67 int main() 68 { 69 while(~scanf("%d",&n)) 70 { 71 if(!n) break; 72 scanf("%d",&m); 73 init(); 74 for(int i=0;i<m;i++) 75 { 76 int x,y,z; 77 scanf("%d%d%d",&x,&y,&z); 78 if(z<a[x][y]) 79 a[x][y]=a[y][x]=z; 80 } 81 for(int i=1;i<=n;i++) 82 scanf("%d",&part[i]); 83 int ans=inf; 84 src=1; 85 dij(); 86 src=2; 87 dij(); 88 for(int i=1;i<=n;i++) 89 { 90 for(int j=1;j<=n;j++) 91 { 92 if(dis[0][i]+dis[1][j]+a[i][j]<ans) 93 ans=dis[0][i]+dis[1][j]+a[i][j]; 94 } 95 } 96 if(ans==inf) 97 puts("-1"); 98 else 99 printf("%d\n",ans); 100 } 101 return 0; 102 }