How Many Maos Does the Guanxi Worth

· 模板题。。。

·我的做法比较水,因为该Boss本身与第n个人校长,是不能被“说服”的。

·一共就30个人,我们这里枚举从[2,n-1]的每个人,删除其所有关系,求解从1到n的单源最短路经。

·在所有的解中找出使得单源最短路经最长的情况。

即求:   Max { Min{删除不同中间人的单源最短路经}}

 

AC Code:

·注意是无向图

  1 #include <iostream>
  2 #include <stdio.h>
  3 #include <algorithm>
  4 #include <cstring>
  5 #include <string.h>
  6 #include <math.h>
  7 #include <queue>
  8 #include <stack>
  9 #include <stdlib.h>
 10 #include <map>
 11 using namespace std;
 12 #define LL long long 
 13 #define sf(a) scanf("%d",&(a));
 14 
 15 /*Dijkstra求单源最短路径 2010.8.26*/
 16 
 17 #include <iostream>
 18 #include<stack>
 19 #define M 210
 20 #define N 210
 21 using namespace std;
 22 
 23 typedef struct node
 24 {
 25     int matrix[N][M];      //邻接矩阵
 26     int n;                 //顶点数
 27     int e;                 //边数
 28 }MGraph;
 29 
 30 void DijkstraPath(MGraph g,int *dist,int *path,int v0)   //v0表示源顶点
 31 {
 32     int i,j,k;
 33     bool *visited=(bool *)malloc(sizeof(bool)*g.n);
 34     for(i=0;i<g.n;i++)     //初始化
 35     {
 36         if(g.matrix[v0][i]>0&&i!=v0)
 37         {
 38             dist[i]=g.matrix[v0][i];
 39             path[i]=v0;     //path记录最短路径上从v0到i的前一个顶点
 40         }
 41         else
 42         {
 43             dist[i]=INT_MAX;    //若i不与v0直接相邻,则权值置为无穷大
 44             path[i]=-1;
 45         }
 46         visited[i]=false;
 47         path[v0]=v0;
 48         dist[v0]=0;
 49     }
 50     visited[v0]=true;
 51     for(i=1;i<g.n;i++)     //循环扩展n-1次
 52     {
 53         int min=INT_MAX;
 54         int u=0;
 55         for(j=0;j<g.n;j++)    //寻找未被扩展的权值最小的顶点
 56         {
 57             if(visited[j]==false&&dist[j]<min)
 58             {
 59                 min=dist[j];
 60                 u=j;
 61             }
 62         }
 63         visited[u]=true;
 64         for(k=0;k<g.n;k++)   //更新dist数组的值和路径的值
 65         {
 66             if(visited[k]==false&&g.matrix[u][k]>0&&min+g.matrix[u][k]<dist[k])
 67             {
 68                 dist[k]=min+g.matrix[u][k];
 69                 path[k]=u;
 70             }
 71         }
 72     }
 73 }
 74 
 75 void showPath(int *path,int v,int v0)   //打印最短路径上的各个顶点
 76 {
 77     stack<int> s;
 78     while(v!=v0)
 79     {
 80         s.push(v);
 81         v=path[v];
 82     }
 83     s.push(v);
 84     while(!s.empty())
 85     {
 86         cout<<s.top()<<" ";
 87         s.pop();
 88     }
 89 }
 90 
 91 int main()
 92 {
 93     int n,e;     //表示输入的顶点数和边数
 94     while(cin>>n>>e && e!=0)
 95     {
 96         int i,j;
 97         int s,t,w;      //表示存在一条边s->t,权值为w
 98         MGraph g,g2;
 99         int v0;
100         int *dist=(int *)malloc(sizeof(int)*n);
101         int *path=(int *)malloc(sizeof(int)*n);
102         for(i=0;i<N;i++)
103             for(j=0;j<M;j++)
104                 g.matrix[i][j]=0;
105         g.n=n;
106         g.e=e;
107         for(i=0;i<e;i++)
108         {
109             cin>>s>>t>>w;
110             //if(g.matrix[s-1][t-1]!=0)
111                 g.matrix[s-1][t-1]=w;
112             g.matrix[t-1][s-1] = w;
113             //else g.matrix[s-1][t-1] = max(g.matrix[s-1][t-1],w);
114         }
115         v0=0;       //输入源顶点
116         DijkstraPath(g,dist,path,v0);
117         int maxc = dist[n-1];
118 
119         g2.n = g.n;g2.e = g.e;
120         for(i=1;i<n-1;i++)
121         {
122             //每次去掉一个顶点!  1~(n-1)
123             memset(g2.matrix,0,sizeof(g2.matrix));
124             dist=(int *)malloc(sizeof(int)*n);
125             path=(int *)malloc(sizeof(int)*n);
126             for(int ii=0;ii<n;ii++)
127                 for(int jj=0;jj<n;jj++)
128                     if(ii==i || jj==i)
129                         g2.matrix[ii][jj] = 0;
130                     else
131                         g2.matrix[ii][jj] = g.matrix[ii][jj];
132             DijkstraPath(g2,dist,path,v0);
133 
134             if(dist[n-1]==INT_MAX){
135                 maxc = -1;break;
136             }
137             maxc = max(maxc,dist[n-1]);
138         }
139         if(maxc==-1)
140             printf("Inf\n");
141         else
142             printf("%d\n",maxc);
143     }
144     return 0;
145 }

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值