POJ 1161 WALLS (FLOYD)

最近和几个高中同学玩得挺HIGH的,真的很高兴啊,一年没见了,各种感叹,大家也都谈了自己的大学生活。果然生活无基友不行啊!

不说了,最近也是很难更新了,同学们都陆续回来了,今天这题也是前天压下来的。

思路:将regions作为构图的点,相邻的regions之间连接一条权值为1的边。用Floyd将所有的regions之间需要的花费求出。最后枚举每个region求出最小花费的那个region。

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int oo=1000000;
inline int min(int a,int b)
{
    return a<b?a:b;
}
int link[255][255];//表示边(i,j)所相接的区域
int mem[35];//第i个人所在点
int n,m,l;
int dis[205][205];//区域i与j之间的距离
struct node
{
    int cnt;
    int p[205];
} data[255];//对于点i,与之相关的区域总数为cnt,存储对应区域p[j](j<cnt)
int main()
{
    int sum,pre,now,fir,anstmp,ans;
    while(cin>>m>>n>>l)
    {
        for(int i=1; i<=l; i++)
            cin>>mem[i];
        memset(link,-1,sizeof(link));
        for(int i=1; i<=n; i++)
            data[i].cnt=0;
        for(int i=1; i<=m; i++)
            for(int j=1; j<=m; j++)
                dis[i][j]=(i==j?0:oo);
        for(int i=1; i<=m; i++)
        {
            cin>>sum>>fir;
            pre=fir;
            data[fir].p[data[fir].cnt++]=i;
            for(int j=1; j<sum; j++)
            {
                cin>>now;
                data[now].p[data[now].cnt++]=i;
                if(link[pre][now]==-1)
                    link[pre][now]=link[now][pre]=i;
                else dis[i][link[pre][now]]=dis[link[pre][now]][i]=1;
                pre=now;
            }
            if(link[pre][fir]==-1)
                link[pre][fir]=link[fir][pre]=i;
            else dis[i][link[pre][fir]]=dis[link[pre][fir]][i]=1;
        }
        for(int k=1; k<=m; k++)
            for(int i=1; i<=m; i++)
                for(int j=1; j<=m; j++)
                    if(dis[i][j]>dis[i][k]+dis[k][j])
                        dis[i][j]=dis[i][k]+dis[k][j];
        ans=oo;
        for(int i=1; i<=m; i++)
        {
            anstmp=0;
            for(int j=1; j<=l; j++)
            {
                int tmp=oo;
                for(int k=0; k<data[mem[j]].cnt; k++)
                    tmp=min(tmp,dis[i][data[mem[j]].p[k]]);
                anstmp+=tmp;
            }
            ans=min(anstmp,ans);
        }
        cout<<ans<<endl;
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值