Welcome, Guest! Sign Up RSS

Clever Space

Friday, 11.22.2024
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);

}




Views: 447 | Added by: dhy0077 | Rating: 0.0/0
Total comments: 0
Only registered users can add comments.
[ Sign Up | Login ]