组织集体活动

  • Description

成功的组织一次集体活动基本要求是所有人都参加,从实践来看,说服所有人需要花费较多的时间。幸运的是,研究发现,在一个集体中,两个人之间花费一定的时间进行单独交流,会同意参加集体活动。现在已知集体中两两之间对参加集体活动达成一致时需要花费的时间t,由于组织集体活动有时间限制,当t大于24小时,我们认为这两人在有限时间不能达成一致,数据不作记录。现在我们采用两两说服的方式来组织这次集体活动,请你根据统计数据,判断能否让所有人都参加,如果能,输出累计花费的最少时间(所有的两两交流所花费时间的累加和)

  • Input

第一行是一个正整数:测试用例数目,最多为100。之后,每个测试用例包括多行:

l 第1行给出一个整数(空格分割),表示集体人数n,2≤n≤200

l 第2行给出两个整数(空格分割),第一个整数表示对某项决定达成一致时间不大于24小时的两人组数目m,第三个整数表示集体活动最初的倡议者k,0≤m≤20100,0≤k≤n-1,集体中每个人用序号表示。

l m行,每行三个整数(空格分割),前两个整数表示两个人,第三个整数表示上述两个人同意参加集体活动需要花费的时间t,0≤n<24。

  • Output

对于每个测试用例:

l 不能让所有人都参加则输出“Impossible”,否则输出累计花费的最少时间

注意:输出部分的结尾要求包含一个多余的空行。

  • Sample Input

2
2
1 0
0 1 2
3
1 0
0 1 2

  • Sample Output

2
Impossible

#include<iostream>
#include<queue>
#include<algorithm>
using namespace std;
#define INF 25
#define N 210
int map[N][N],cost[N],n,used[N];
void dijkstra(int beg)
{
    int i,j;
    memset(used,0,sizeof(used));
    for(i=0;i<=n;i++)
        cost[i]=map[i][beg];
    cost[beg]=0;
    used[beg]=1;
    for(i=1;i<n;i++)
    {
        int flag=-1,min=INF;
        for(j=0;j<n;j++)
        {
            if(!used[j] && cost[j]<min)
                flag=j,min=cost[j];
        }
        if(flag!=-1)
        {
            used[flag]=1;
            for(j=0;j<n;j++)
                if(!used[j] && cost[j]>map[j][flag])
                    cost[j]=map[j][flag];
        }
    }
}

int main()
{
    int times;
    scanf("%d",&times);
    while(times--)
    {
        int i,j,ok=1,beg,m,x,y,ans=0,c;
        scanf("%d",&n);
        for(i=0;i<n;i++)
        {
            for(j=0;j<n;j++)
                map[i][j]=INF;
        }
        scanf("%d %d",&m,&beg);
        for(i=0;i<m;i++)
        {
            scanf("%d %d %d",&x,&y,&c);
            map[x][y]=map[y][x]=c;
        }
        dijkstra(beg);
        for(i=0;i<n;i++)
        {
            if(!used[i])
            {
                ok=0;break;
            }
        }
        if(ok==0)
        {
            printf("Impossible\n");
            continue;
        }
        for(i=0;i<n;i++)
            ans+=cost[i];
        printf("%d\n",ans);
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值