Rings'n'Ropes - UVa 10985 Floyd

76 篇文章 0 订阅

Rings'n'Ropes
Time Limit: 3 seconds

"Well, that seems to be the situation. But,
I don't want that, and you don't want that,
and Ringo here definitely doesn't want that."

Jules Winnfield

I have n tiny rings made of steel. I also have m pieces of rope, all of exactly the same length. The two ends of each piece of rope are tied to two different rings.

I am going to take one of the rings, L, into my left hand, and another ring, R into my right hand. Then I will pull the whole structure apart as hard as I can. Some of the ropes will be streched horizontally because of this. Others will hang down or bend out of shape. If I want the number of horizontally stretched ropes to be as large as possible, which L and R should I pick?

Assume that the stretching of ropes in negligible, they all have negligible thickness and are free to slide around the rings that they are tied to. The thickness and radius of each ring is negligible, too.

Input
The first line of input gives the number of cases, NN test cases follow. Each one starts with two lines containing n ( 2<= n<=120 ) and m ( 0<= m<= n( n-1)/2 ). The next m lines will each contain a pair of different rings (integers in the range [0, n-1]). Each pair of rings will be connected by at most one rope.

Output
For each test case, output the line containing "Case #x:", followed by the largest number of ropes that I can stretch horizontally by picking a pair of rings, L and R.

Sample InputSample Output
4
2 
1
0 1
3
3
0 1
1 2
2 0
6
6
0 1
0 5
1 3
5 4
3 2
4 2
6
7
0 1
0 5
1 3
1 4
5 4
3 2
4 2
Case #1: 1
Case #2: 1
Case #3: 6
Case #4: 7


题意:有n个环用绳子连起来,问当你选择其中两个拉直时,最多有多少绳子是水平拉直的。

思路:Floyd后,最短路径就是拉直后的长度,然后就搜索其中dp[i][v]+dp[v][j]==dp[i][j] && dp[i][u]!=dp[i][v],这样的话u和v之间连接的绳子就是水平的。

AC代码如下:

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
struct node
{
    int v,next;
}edge[30010];
int T,t,n,m,dp[130][130],INF=1e9,tot,Head[130];
bool vis[130];
queue<int> qu;
void add(int u,int v)
{
    edge[tot].v=v;
    edge[tot].next=Head[u];
    Head[u]=tot;
    tot++;
}
int main()
{
    int i,j,k,u,v,maxn,ret;
    scanf("%d",&T);
    for(t=1;t<=T;t++)
    {
        scanf("%d%d",&n,&m);
        for(i=0;i<n;i++)
           for(j=0;j<n;j++)
              dp[i][j]=INF;
        for(i=0;i<n;i++)
           dp[i][i]=0;
        tot=0;
        memset(Head,-1,sizeof(Head));
        for(i=1;i<=m;i++)
        {
            scanf("%d%d",&u,&v);
            dp[u][v]=dp[v][u]=1;
            add(u,v);
            add(v,u);
        }
        for(i=0;i<n;i++)
           for(j=0;j<n;j++)
              for(k=0;k<n;k++)
                 dp[i][j]=min(dp[i][j],dp[i][k]+dp[k][j]);
        maxn=0;
        for(i=0;i<n;i++)
           for(j=i+1;j<n;j++)
           if(dp[i][j]<INF)
           {
               ret=0;
               memset(vis,0,sizeof(vis));
               vis[i]=0;vis[j]=1;
               qu.push(j);
               while(!qu.empty())
               {
                   u=qu.front();
                   qu.pop();
                   for(k=Head[u];k>=0;k=edge[k].next)
                   {
                       v=edge[k].v;
                       if(dp[i][v]+dp[v][j]==dp[i][j] && dp[i][u]!=dp[i][v])
                       {
                           ret++;
                           if(vis[v]==0)
                           {
                               vis[v]=1;
                               qu.push(v);
                           }
                       }
                   }
               }
               maxn=max(maxn,ret/2);
           }
        printf("Case #%d: %d\n",t,maxn);
    }
}



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值