hdu 4313 Matrix

http://acm.hdu.edu.cn/showproblem.php?pid=4313

思路:有点贪心吧。先设a为b、c的father,分以下三种情况考虑:
1、如果a有机器人,b或c也有机器人,则一定要把a和b,c断开。
2、如果a、c没有机器人,且b有机器人,设d有机器人,且d为a的father,则问题可以转化成a有机器人,取b到d路径上的最小值。
3、如果a没有机器人,且b、c有机器人,则如果a到b的路径大于a到c的路径,则把b的机器人放到a点上,a到c的路径权值加到ans,反之~~~~。
这样每次都让叶子结点开始向上归约。每个结点都会进一次队,最后的时间复杂度为O(n).
 
View Code
#include<stdio.h>
#include<string.h>
#define maxn 100005
struct nd{
    int v,next,c;
}edge[200005];
int flag[maxn],vis[maxn],in[maxn],head[maxn],ecnt,as[maxn],que[maxn];
int Min(int x,int y){return x>y?y:x;}
void add(int u,int v,int w)
{
    edge[ecnt].v = v;
    edge[ecnt].c = w;
    edge[ecnt].next = head[u];
    head[u] = ecnt++;
}
int main()
{
    int a,b,c,i,n,k,t,ts,te;
    int inf = 1<<30;
    long long ans;
    scanf("%d",&t);
    while(t--){
        scanf("%d %d",&n,&k);
        memset(flag,0,sizeof(flag));
        memset(vis,0,sizeof(vis));
        memset(in,0,sizeof(in));
        memset(as,0,sizeof(as));
        memset(head,-1,sizeof(head));
        ecnt = 0;
        for(i = 0; i < n - 1; ++ i){
            scanf("%d %d %d",&a,&b,&c);
            add(a,b,c);
            add(b,a,c);
            in[a]++; in[b]++;
        }
        for(i = 0; i < k; ++ i){
            scanf("%d",&c);
            flag[c]=1;
        }
        te = ts = 0;
        for(i = 0; i < n; ++ i)
        if(in[i]==1){
            if(flag[i]) as[i]=inf;
            que[te++]=i;
        }
        ans = 0;
        while(ts^te){
            a = que[ts++];
            vis[a] = 1;
            for(i = head[a]; i != -1; i = edge[i].next){
                b = edge[i].v;
                c = edge[i].c;
                if(vis[b])continue;
                as[a] = Min(c,as[a]);//取路径上的最小值
                in[b]--;
                if(in[b]==1){
                    if(flag[b]) as[b] = inf;
                    que[te++] = b;
                }
                if(flag[b]){//第1种情况
                    ans += as[a];
                }else if(as[a]){//第3种情况
                    if(as[b]>as[a]) ans += as[a];
                    else{
                        ans += as[b];
                        as[b] = as[a];
                    }
                }
            }
        }
        printf("%I64d\n",ans);
    }
    return 0;
}

 

posted on 2012-07-28 11:45  aigoruan  阅读(220)  评论(0)    收藏  举报

导航