UVa 10985 Rings'n'Ropes / floyd + dfs

n个戒指 和m条长度为1 的绳子

求左右手拿住任意2个戒指 最多几条绳子被拉直

拿住哪2个不知道 所以两两枚举

对于2个戒指之间 可以考虑最短路 然后可能有很多条最短路 在路径统计下就行

看懂样例怎么出来的就知道怎么回事了

样例3就是一个环 拉住0 和 2 你们就有2条最短路 每条都是3

样例4是一样的

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
const int MAX = 130;
int a[MAX][MAX];
int map[MAX][MAX];
bool vis[MAX][MAX];
int n,m;
int cnt;
void floyd()
{
	int i,j,k;
	for(k = 0; k < n; k++)
		for(i = 0; i < n; i++)
			for(j = 0; j < n; j++)
				a[i][j] = min(a[i][j],a[i][k]+a[k][j]);
}

void bfs(int s,int e)
{
	queue <int> q;
	q.push(s);
	int i;
	while(!q.empty())
	{
		int u = q.front();
		q.pop();
		for(i = 0; i < n; i++)
		{
			if(vis[u][i])
				continue;
			if(!map[u][i])
				continue;
			if(a[e][i] + 1 == a[e][u])
			{
				cnt++;
				vis[u][i] = vis[i][u] = true;
				q.push(i);
			}
		}
	}
}
int main()
{
	int t,cas = 1;
	int i,j;
	int s,e;
	scanf("%d",&t);
	while(t--)
	{
		memset(a,0,sizeof(a));
		memset(map,0,sizeof(map));
		scanf("%d %d",&n,&m);
		for(i = 0; i < n; i++)
			for(j = 0; j < n; j++)
			{
				if(i == j)
					a[i][j] = 0;
				else
					a[i][j] = 999999999;
			}
		for(i = 0; i < m; i++)
		{
			scanf("%d %d",&s,&e);
			a[s][e] = a[e][s] = 1;
			map[s][e] = map[e][s] = 1;
		}
		floyd();
		int max = 0;
		for(i = 0; i < n; i++)
		{
			for(j = i+1; j < n; j++)
			{
				if(a[i][j] == 999999999)
					continue;
				
				memset(vis,false,sizeof(vis));
				cnt = 0;
				bfs(i,j);
				if(max < cnt)
					max = cnt;
			}
		}
		//printf("%d %d\n",a[0][1],a[1][0]);
		printf("Case #%d: %d\n",cas++,max);
	}
	return 0;
}


 

你可能感兴趣的:(UVa 10985 Rings'n'Ropes / floyd + dfs)