pku 3660 Cow Contest floy灵活使用

http://poj.org/problem?id=3660

才开始看到题目给我的第一印象就是拓扑排序,自己yy了一下不对。考虑到如果第i个奶牛的位置确定的话就必须知道他与其他n-1个奶牛的对应关系,所以A->B->C这样A也一定能够打败C所以要有A->C连一条线。用floyd将需要连接的边链接,然后统计每个点的度数只要>=n - 1即可,最后统计个数。

这道题目和hdu 的这道题目floyd的灵活运用有异曲同工之妙:http://acm.hdu.edu.cn/showproblem.php?pid=4034

View Code
#include <iostream>
#include <cstring>
#include <cstdio>
#define N 107
#define inf 9999999
using namespace std;

int map[N][N],d[N];
bool f[N][N];
int n,m;

void init()
{
    int i,j;
    for (i = 0; i < N; ++i)
    {
        d[i] = 0;
        for (j = 0; j < N; ++j)
        {
            if (i == j) map[i][j] = 0;
            else        map[i][j] = inf;
            f[i][j] = false;
        }
    }
}
void floyd()
{
    int i,j,k;
    for (k = 1; k <= n; ++k)
    {
        for (i = 1; i <= n; ++i)
        {
            for (j = 1; j <= n; ++j)
            {
                if (i != j && j != k && k != i && map[i][k] == 0 && map[k][j] == 0)
                {
                    if (!f[i][j] && map[i][j] > map[i][k] + map[k][j])
                    {
                        f[i][j] = true;
                        map[i][j] = map[i][k] + map[k][j];
                        d[i]++; d[j]++;
                    }
                }
            }
        }
    }
}
int main()
{
    init();
    int i,x,y,z;
    scanf("%d%d",&n,&m);
    for (i = 0; i < m; ++i)
    {
        scanf("%d%d",&x,&y);
        map[x][y] = 0;
        d[x]++; d[y]++;
        f[x][y] = true;//防止重复相同的边
    }
    floyd(); int ct = 0;
    for (i = 1; i <= n; ++i)
    {
        if (d[i] >= n - 1) ct++;
    }
    printf("%d\n",ct);
    return 0;
}
posted @ 2012-05-06 10:35  E_star  阅读(240)  评论(2编辑  收藏  举报