blockenemy

在一款虚拟城市游戏中,玩家面临敌方踩点的挑战。为孤立敌人,玩家需要切断街道连接,但每条街道的切断会引发市民不满。任务是找出使所有敌人位置两两不联通所需的最小总不满值。输入包括城市节点、街道信息和敌人位置,输出是最小不满值。解决方法是按边权排序并使用并查集策略。
摘要由CSDN通过智能技术生成

blockenemy

Time Limits: 1000 ms Memory Limits: 128000 KB

Description
你在玩电子游戏的时候遇到了麻烦。。。。。。 你玩的游戏是在一个虚拟的城市里进行,这个城市里有n个点,都从0~n-1编了号,每两个点之间有且仅有一条路径。现在,你的敌人到这个城市来踩点了!!!为了阻止他们更好的踩点, 你决定切断他们所有踩点人员的联系,使他们孤军作战,然后在各个击破。但是这就要切断某些街道,而你每切断一条路,市民就会产生相对的不满值,不满值越大,城市的和谐度就越小。所以你现在需要知道为了使踩点人员所在的点两两之间不联通所切断的边产生的最小不满值是多少?

Input
第一行一个数:n n<=50 以下n-1行,每行3个数 a,b,c 表示a点和b点之间有条路,切断这条路的不满值为c 以下若干行 每行一个数,表示踩点人员的位置

Output
一个数,最小不满值

Sample Input

5 
1 0 1 
1 2 2 
0 3 3 
4 0 4 
3 
2 
4

Sample Output

4

不用多说了吧,将边按照边权为关键字,大到小排序,然后并查集,不用多说了吧。

Codes:

#include<cstdio>
#include<cstring>
#define fo(i,x,y) for(int i=x;i<=y;i++)
using namespace std;

int n,a[100][3],ans=0,fa[50],tot=0,top=0;
char num;
bool bz[50];

void insert(int,int,int);
void q(int,int);
int GetFather(int);

void swap(int &a,int &b){int c=a;a=b;b=c;}

int main()
{
    scanf("%d",&n);
    fo(i,1,n-1)
    {
        int x,y,z;
        scanf("%d%d%d",&x,&y,&z);
        insert(x,y,z);
        tot+=z;
    }scanf("\n");
    q(1,top);
    memset(bz,0,sizeof(bz));
    for(;;)
    {
        num=getchar();
        if(num<'0' || num>'9')break;
        int x=num-'0';
        for(;;)
        {
            num=getchar();
            if(num<'0' || num>'9')break;
            x+=x*9+(num-'0');
        }
        bz[x]=1;
    }
    fo(i,0,n-1)fa[i]=i;
    fo(i,1,top)
    {
        int A=GetFather(a[i][1]),B=GetFather(a[i][0]);
        if(!(bz[A]) || !(bz[B]))
        {
            if(bz[A] || bz[B])bz[B]=1;
            fa[A]=B;
            ans+=a[i][2];
        }
    }
    printf("%d",tot-ans);
}

void insert(int x,int y,int z)
{
    a[++top][0]=x;
    a[top][1]=y;
    a[top][2]=z;
}

void q(int h,int t)
{
    int l=h,r=t,m=a[(h+t)>>1][2];
    do{
        while(a[l][2]>m)l++;
        while(a[r][2]<m)r--;
        if(l<=r)
        {
            swap(a[l][0],a[r][0]);
            swap(a[l][1],a[r][1]);
            swap(a[l++][2],a[r--][2]);
        }
    }while(l<=r);
    if(h<r)q(h,r);if(l<t)q(l,t);
}

int GetFather(int x)
{
    if(fa[x]==x)return x;
    fa[x]=GetFather(fa[x]);
    return fa[x];
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值