uva 10985 Rings'n'Ropes 解题报告

来源:互联网 发布:怎样投诉淘宝网 编辑:程序博客网 时间:2024/06/05 07:16

题意:题目意思看了好久才看懂

            有N个戒指,M条长度相同的绳子,然后双手任取两个戒指用力往左右拉,使得中间有些绳子会绷直,问最多能绷直的绳子条数?

分析:把戒指看成点,可知两个点拉长的长度必定是两点之间的最短距离,而拉直的线必定是最短距离上的。但是最短距离上的点之间的连线确不一定能绷直。

如下图:


1,2之间2,3之间能绷直,但是1,3之间不能绷直。 我们可以得出如果点对属于同一级则之间的线不能绷直(同一级指到起始点的距离相等),所以我们先做一遍Floyed,然后枚举左右的两个点,找出这两点最短路上的所有点,在枚举这些点对找能绷直的绳。

c++代码

#include<cstdio>#include<cstring>int a[150][150],s[150];int f[150][150];int n;const int INF = 9999999;void init(){    int m,i,j,x,y;    scanf("%d%d",&n,&m);    memset(a,0,sizeof(a));    for (i = 1; i <= n; i++)    for (j = 1; j <= n; j++)        f[i][j] = INF;    //    for (i = 1; i <= m; i++)    {        scanf("%d%d",&x,&y);        x++,y++;        a[y][x] = a[x][y] = 1;        f[x][y] = f[y][x] = 1;    }    for (i = 1; i <= n; i++)    {        f[i][i] = 0;        a[i][i] = 1;    }}void floyed(){    int k,i,j;    for (k = 1; k <= n; k++)    for (i = 1; i <= n; i++)    for (j = 1; j <= n; j++)    if (f[i][j] > f[i][k] + f[k][j])        f[i][j] = f[i][k] + f[k][j];}void work(){    int i,j,k,k1,k2,tot,ans,ans1;    ans = 0;    for (i = 1; i <= n; i++)    for (j = i+1; j <= n; j++)    if (i != j && f[i][j] != INF)    {        tot = 0;        ans1 = 0;        for (k = 1; k <= n; k++)            if (f[i][k] + f[k][j] == f[i][j]) s[++tot] = k;        for (k1 = 1; k1 <= tot; k1++)        for (k2 = k1 + 1; k2 <= tot; k2++)        {            if (a[s[k1]][s[k2]] == 1 && f[i][s[k1]] != f[i][s[k2]]) ans1++;        }        if (ans < ans1) ans = ans1;    }    printf("%d\n",ans);}int main(){    int temp,kase;    scanf("%d",&temp);    for (kase = 1; kase <= temp; kase++)    {        init();        floyed();        printf("Case #%d: ",kase);        work();    }    return 0;}

原创粉丝点击