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 }
原文地址:https://www.cnblogs.com/Missa/p/2908992.html