sgu323 Aviamachinations

来源:互联网 发布:汉武大帝知乎 编辑:程序博客网 时间:2024/06/08 13:11
题目大意:n个城市,m个航空公司,k条航线,接下来的k行,就是每条航线的起点终点,对应航空公司和这条线的权重,现在只保留一个航空公司要求仍够可以使所有城市直接或间接相连,对于不属于这个航空公司的航线需要出钱买,价格就是这条线的权重,输出最小的花费,保留哪家航空公司以及要够买的航线数(q),接下来的q行输出要购买的航线的编号
解题思路:先按每条航线对应的花费做最小生成树,然后枚举航空公司(i->1-M),意思是保留第i家航空公司,然后把本身属于这家航空公司的航线连起来,最后按照最小生成树查哪些点没有连起来,再利用最小生成树中对应的边把这两点连起来,答案要求最小值,更新一下就好了。
#include <iostream>#include <cstdio>#include <algorithm>#include <cstring>#define R 200010const int inf = 1 << 29;using namespace std;int counter;struct edge{    int u,v,w,air,flag;}e[R],tree[R];struct node{    int parent;}a[R],nod[R];int sell[2500][2500],rel[2500];bool cmp(edge p,edge q){    return p.w<q.w;}bool cmp1(int p,int q){    return p<q;}void Initial(int N){    for(int i=1;i<=N;i++){            a[i].parent=i;    }}void Init(int N){    for(int i=1;i<=N;i++){        nod[i].parent=i;    }}int Find(int k){    if(a[k].parent!=k){        a[k].parent=Find(a[k].parent);    }    return a[k].parent;}int find2(int k){    if(nod[k].parent!=k){        nod[k].parent=find2(nod[k].parent);    }    return nod[k].parent;}void krus(int N,int K){    Initial(N);    for(int i=1;i<=K;i++){        int l=Find(e[i].u);        int r=Find(e[i].v);        if(l!=r){            tree[counter].u=e[i].u;            tree[counter].v=e[i].v;            tree[counter].w=e[i].w;            tree[counter].air=e[i].air;            tree[counter].flag=e[i].flag;            counter++;            a[r].parent=a[l].parent;        }    }}void Compute(int M,int N,int K){    int s,shu;    int ans=inf,buy;    for(int i=1;i<=M;i++){        s=1;        int tmp=0;        Init(N);        for(int j=1;j<=K;j++){            if(e[j].air==i){                int l=find2(e[j].u);                int r=find2(e[j].v);                if(l!=r){                    nod[r].parent=nod[l].parent;                }            }        }        for(int k=1;k<counter;k++){            int u=tree[k].u,v=tree[k].v;            int l=find2(u);            int r=find2(v);            if(l!=r){            sell[i][s]=tree[k].flag;            s++;            tmp+=tree[k].w;            nod[r].parent=nod[l].parent;            }        }        if(ans>tmp){            ans=tmp;            buy=i;            shu=s-1;        }    }    for(int i=1;i<=shu;i++){        rel[i]=sell[buy][i];    }    printf("%d %d %d\n",ans,buy,shu);    sort(rel+1,rel+shu+1,cmp1);    for(int i=1;i<=shu;i++){        printf("%d\n",rel[i]);    }}int main(){    int N,M,K;    while(~scanf("%d%d%d",&N,&M,&K)){        counter=1;        for(int i=1;i<=K;i++){            scanf("%d%d%d%d",&e[i].u,&e[i].v,&e[i].air,&e[i].w);            e[i].flag=i;        }        sort(e+1,e+K+1,cmp);        krus(N,K);        Compute(M,N,K);    }    return 0;}

0 0
原创粉丝点击