1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83
|
#include <cstdlib> #include <algorithm> #include <cstring> #include <cctype> #define INF 2000000000 using namespace std; typedef long long ll; struct { int u,v,c1,c2; }; Edge edge[20005]; int n,k,m,par[10005],q1[20005],q2[20005],vis[20005]; bool cmp1(int a,int b){ return edge[a].c1<edge[b].c1; } bool cmp2(int a,int b){ return edge[a].c2<edge[b].c2; } int Find(int t){ if(par[t]==t)return t; return (par[t]=Find(par[t])); } void unite(int a,int b){ if(Find(a)==Find(b))return ; par[Find(a)]=Find(b); } int judge(int M){ int cnt=0,tot=n,at,ans=0,u,v,c; for(int i=1;i<=n;i++)par[i]=i; memset(vis,0,sizeof(vis)); for(at=0;tot>n-k&&at<m;at++){ if(edge[q1[at]].c1>M)continue; u=edge[q1[at]].u,v=edge[q1[at]].v, c=edge[q1[at]].c1; if(Find(u)!=Find(v)) unite(u,v),ans+=c,vis[q1[at]]=1,tot--; } if(at==m&&tot!=n-k)return -1; for(at=0;tot>1&&at<m;at++){ if(edge[q2[at]].c2>M||vis[q2[at]])continue; u=edge[q2[at]].u,v=edge[q2[at]].v, c=edge[q2[at]].c2; if(Find(u)!=Find(v)) unite(u,v),ans+=c,vis[q2[at]]=2,tot--; } if(at==m&&tot!=1)return -1; return ans; } int read(){ int f=1,x=0;char c=getchar(); while(c<'0'||c>'9'){if(c=='-')f=-f;c=getchar();} while(c>='0'&&c<='9')x=x*10+c-'0',c=getchar(); return f*x; } void init(){ scanf("%d%d%d",&n,&k,&m); for(int i=0;i<m;i++) scanf("%d%d%d%d",&edge[i].u,&edge[i].v,&edge[i].c1,&edge[i].c2); for(int i=0;i<m;i++) q1[i]=q2[i]=i; sort(q1,q1+m,cmp1); sort(q2,q2+m,cmp2); } void solve(){ int L=0,R=INF,M,ans; while(R-L){ M=(L+R)/2; ans=judge(M); if(ans>=0) R=M; else L=M+1; } printf("%dn",L); judge(L); for(int i=0;i<m;i++) if(vis[i])printf("%d %dn",i+1,vis[i]); } int main(){ init(); solve(); return 0; }
|
近期评论