题目的意思就是n枚戒指,被m条线串起来了.问把哪两个戒指绷紧,拉直的先最多.
例如
0-1-2-3 如果把戒指0和3拉直,那么中间有3条线.
0 - 1
\ 2 / 如果是这样,最多绷紧一条线.
那么任意两点拉直的话,会有几条线绷紧呢,就是处在这两点最短路上的边的数量.
所以我们找到两个点,找到它的所有最短路,最短路上所有边共几条,答案就是几.
第一步用floyd求任意两点的最短路.
然后遍历任意两点 ,找出最多的一个值.
AC代码:
#include<stdio.h>
#include<string.h>
const int N = 150;
const int M = N * N / 2 ;
const int INF = 0x3f3f3f3f;
int d[N][N];
int g[N][N];
int vis[N][N];
int n,m ,res;
void floyd() {
for (int k = 0 ; k < n ;k++) {
for (int i = 0 ; i < n ;i++) {
for (int j = 0 ; j < n ;j++) {
d[i][j] = d[i][j] < d[i][k] + d[k][j] ? d[i][j] : d[i][k] + d[k][j] ;
}
}
}
}
void dfs(int x , int x1 ,int y1) {
for (int i = 0 ; i < n ;i++) {
if(g[x][i]) {
if (d[x1][x] + g[x][i] + d[i][y1] == d[x1][y1] && !vis[x][i]) {
vis[i][x] = vis[x][i] = 1;
res++;
dfs(i , x1, y1);
}
}
}
}
int main () {
int t ;
int cas = 1;
scanf("%d",&t);
while (t--) {
int a,b;
memset(g , 0 , sizeof(g));
memset(d , INF , sizeof(d));
scanf("%d%d",&n,&m);
for (int i = 0 ; i < n ;i++ ) {
d[i][i] = 0;
}
for (int i = 0 ; i < m ;i++) {
scanf("%d%d",&a,&b);
d[a][b] = d[b][a] = 1;
g[a][b] = g[b][a] = 1;
}
floyd();
int mm = 0;
for (int i = 0 ; i < n ;i++) {
for (int j = i + 1 ; j < n ;j++) {
memset(vis , 0 ,sizeof(vis));
res = 0;
dfs(i , i ,j);
if (res > mm)
mm = res;
}
}
printf("Case #%d: %d\n",cas++ ,mm);
}
}