uva 10952 Rings'n'Ropes

原题:
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, N. N 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 Input
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
Sample Output
Case #1: 1
Case #2: 1
Case #3: 6
Case #4: 7

中文:
给你n个戒指,用m个没有弹力的相同长度的绳子连接起来,现在左手拿起其中一个戒指,右手拿起另外一个戒指,向两侧使劲拉伸,能绷紧的绳子数是多少?

#include<bits/stdc++.h>
using namespace std;
int mat[121][121];
int n,m,t;
const int inf=999999;
void floyed()
{
    for(int k=0;k<n;k++)
    {
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<n;j++)
                mat[i][j]=min(mat[i][j],mat[i][k]+mat[k][j]);
        }
    }
}


int solve()
{
    int ans=0,res;
    for(int i=0;i<n;i++)
    {
        for(int j=i+1;j<n;j++)
        {
            if(mat[i][j]!=inf)
            {
                vector<int> tmp;
                for(int k=0;k<n;k++)
                {
                    if(mat[i][j]==mat[i][k]+mat[k][j])
                        tmp.push_back(k);
                }
                res=0;
                for(int k=0;k<tmp.size();k++)
                {
                    for(int p=k+1;p<tmp.size();p++)
                    {
                        int a,b;
                        a=tmp[k];
                        b=tmp[p];
                        if(mat[a][b]==1&&mat[i][a]!=mat[i][b])
                            res++;
                    }
                }
                ans=max(ans,res);
            }
        }
    }
    return ans;
}

int main()
{
    int k=1;
    ios::sync_with_stdio(false);
    cin>>t;
    while(t--)
    {
        cin>>n>>m;
        for(int i=0;i<n;i++)
            for(int j=0;j<n;j++)
                if(i==j)
                    mat[i][j]=0;
                else
                    mat[i][j]=inf;
        for(int i=1;i<=m;i++)
        {
            int a,b;
            cin>>a>>b;
            mat[a][b]=mat[b][a]=1;
        }
        floyed();
        int ans=solve();
        cout<<"Case #"<<k++<<": "<<ans<<endl;
    }
    return 0;
}

解答:

说来惭愧,读题的时候没注意是左右手各拿起“一个”戒指!我把此题当成二分图最大匹配的方法来解,样例没算明白不说,最后死活还没想出来,看别人的中文解释看了半天才明白这题的描述是怎么回事。

两只手各拿一个戒指,使劲拉伸,那么绷紧的绳子肯定是两个戒指之间的最短路。首先用floyed算法计算出所有戒指的最短路,再找出最短路路径当中的所有节点记录下来。

如果绳子能够绷紧,那么这个用戒指和绳子连接成的类似”渔网“结构,肯定是被拉伸成一条一条直线,中间会有垂下来的戒指。在枚举中间节点的路径时,如果起点到两个中间点的距离相同,那么这两个点之间就会又一个垂下来。所以mat[i][a]!=mat[i][b]为满足条件的路径

这里写图片描述

找到一篇描述的很清楚的博客

http://blog.csdn.net/l123012013048/article/details/41910301

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值