#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#define R 200010
const 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;
}
sgu323 Aviamachinations
題目大意:n個城市,m個航空公司,k條航線,接下來的k行,就是每條航線的起點終點,對應航空公司和這條線的權重,現在只保留一個航空公司要求仍夠可以使所有城市直接或間接相連,對於不屬於這個航空公司的航線需要出錢買,價格就是這條線的權重,輸出最小的花費,保留哪家航空公司以及要夠買的航線數(q),接下來的q行輸出要購買的航線的編號
解題思路:先按每條航線對應的花費做最小生成樹,然後枚舉航空公司(i->1-M),意思是保留第i家航空公司,然後把本身屬於這家航空公司的航線連起來,最後按照最小生成樹查哪些點沒有連起來,再利用最小生成樹中對應的邊把這兩點連起來,答案要求最小值,更新一下就好了。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.