Main » 2013 October 16 » [模拟赛NOIP2010]喜欢宠物的 GF
6:05 AM [模拟赛NOIP2010]喜欢宠物的 GF |
哈哈,想到了。若不考虑直接召唤,这显然是棵生成树。若A能召唤B,添加一条边从A到B,权值为代价,这条边显然是无向的。然后直接召唤怎么办呢?想想,直接召唤的东西是从哪里来的?有时候,就是要天真一点。建空节点吧!!!然后kruskal,然后就没有然后了。时间复杂度为O(NE+ElogE)#include<cstdio>#include<cstdlib>#include<cstring>#include<set>#include<algorithm>#include<map>#include<vector>#include<queue>#include<iostream>#include<string>#include<cmath>#define N 100010#define FOR(i,a,b) for(i=(a);i<=(b);i++)#define ROF(i,a,b) for(i=(a);i>=(b);i--)typedef long long LL;using namespace std;struct edge{int x,y,w;};edge e[N];int f[N],A[N],n,m;int cmp(edge a,edge b){return a.w<b.w;}int getf(int x){if (f[x]!=x) f[x]=getf(f[x]);return f[x];}void merge(int a,int b){int fa=getf(a);int fb=getf(b);f[fa]=fb;}int main(){scanf("%d",&n);int L=0,a,b,W,i,j;FOR(i,1,n){scanf("%d",&A[i]);e[++L].x=n+1;e[L].y=i;e[L].w=A[i];}scanf("%d",&m);FOR(i,1,m){scanf("%d%d%d",&a,&b,&W);e[++L].x=a;e[L].y=b;e[L].w=W;}sort(e+1,e+1+L,cmp);int ans=2e9;FOR(i,1,n){int res=0,cnt=0;FOR(j,1,n+1) f[j]=j;FOR(j,1,L){if (e[j].x==i||e[j].y==i) continue;int X=e[j].x,Y=e[j].y;int fx=getf(X),fy=getf(Y);if (fx==fy) continue;merge(fx,fy);res+=e[j].w;if (res>ans) break;cnt++;if (cnt==n-1) break;}if ((ans>res)&&(cnt==n-1)) ans=res;}printf("%d\n",ans);} |
|
Total comments: 0 | |