首页 > 代码库 > poj2139

poj2139

牛们最近在拍电影,所以他们准备去玩一个游戏——“六度分割”的变体。
游戏是这样进行的:每个牛离自己的距离是0度,如果两个不同的牛同时出现在一个电影里,那么他们之间的距离为1度,如果两只牛从未一起工作,但它们都与第三只牛一起工作,那么他们之间的距离为2度。
这N(2<=N<=300)头牛对找出那只牛与所有牛之间的平均距离最短感兴趣。当然,不算上他自己。这些牛拍了M(1<=M<=10000)部电影,并且保证每两个牛之间都有一定的关系。

 原题地址:http://poj.org/problem?id=2139

#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
int mapa[500][500];
int m,n;
int q[500];
int inq[500];
int h[500];
int d[500];
int a[500];
int ans=10000000;
int cnt=0;
struct Edge{int u,v,next;}e[5000000];
void spfa(int x){
    memset(q,0,sizeof(q));
    memset(inq,0,sizeof(inq));
    memset(d,127,sizeof(d));
    d[x]=0;
    q[0]=x;
    inq[x]=1;
    int head=0,tail=1;
    while(head!=tail){
        int u=q[head++%400];
        inq[u]=0;
        for(int i=h[u];i>0;i=e[i].next){
            int v=e[i].v;
            if(d[u]+1<d[v]){
                d[v]=d[u]+1;
                if(!inq[v]){
                    inq[v]=1;
                    q[tail++%400]=v;
                }
            }
        }
    }
}
int main(){
    cin>>n>>m;
    for(int i=1;i<=m;i++){
        int x;
        cin>>x;
        memset(a,0,sizeof(a));
        for(int j=1;j<=x;j++){
            scanf("%d",&a[j]);
        }
        for(int j=1;j<=x;j++){
            for(int k=1;k<=x;k++){
                mapa[a[j]][a[k]]=mapa[a[k]][a[j]]=1;
            }
        }
    }
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            if(mapa[i][j]){
                e[++cnt]=(Edge){i,j,h[i]};h[i]=cnt;
            }
        }
    }
    for(int i=1;i<=n;i++){
        spfa(i);
        int sum=0;
        for(int j=1;j<=n;j++){
            sum+=d[j];
        }
        ans=min(ans,sum);//    cout<<sum<<endl;
    }
    /*for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            cout<<mapa[i][j]<<"  "<<endl;
            }
            cout<<endl;
        }*/
    cout<<ans*100/(n-1)<<endl;
    return 0;
} 

 

poj2139