码迷,mamicode.com
首页 > 编程语言 > 详细

【朱-刘算法】【最小树形图】hdu6141 I am your Father!

时间:2017-08-18 00:05:45      阅读:254      评论:0      收藏:0      [点我收藏+]

标签:cst   tle   eof   nod   using   网上   cstring   ace   ems   

题意:给你一张带权有向图,让你求最大树形图。并在此前提下令n号结点父亲的编号最小。

比赛的时候套了个二分,TLE了。

实际上可以给每个边的权值乘1000,对于n号结点的父边,加上(999-父结点编号)大小的权值,这样即可保证最大树形图的前提下,n号结点父亲的编号最小。

网上找了个朱-刘算法的板子,把边权取负就能跑最大树形图了。

#include <cstdio>  
#include <string>  
#include <cstring>  
#define MAXN 1005  
#define MAXM 10005  
using namespace std;  
struct node  
{  
    int u, v;  
    int w;  
}edge[MAXM];  
int pre[MAXN], id[MAXN], vis[MAXN], n, m;  
int in[MAXN];  
typedef int type;
#define INF 2000000000
type Directed_MST(int root, int V, int E)  
{  
    type ret = 0;  
    while(true)  
    {  
        //1.?????  
        for(int i = 0; i < V; i++) in[i] = INF;  
        for(int i = 0; i < E; i++)  
        {  
            int u = edge[i].u;  
            int v = edge[i].v;  
            if(edge[i].w < in[v] && u != v) {pre[v] = u; in[v] = edge[i].w;}  
        }  
        for(int i = 0; i < V; i++)  
        {  
            if(i == root) continue;  
            if(in[i] == INF) return -1;//???????????,???????  
        }  
        //2.??  
        int cnt = 0;  
        memset(id, -1, sizeof(id));  
        memset(vis, -1, sizeof(vis));  
        in[root] = 0;  
        for(int i = 0; i < V; i++) //?????  
        {  
            ret += in[i];  
            int v = i;  
            while(vis[v] != i && id[v] == -1 && v != root)  //?????????,?????????,???????  
            {  
                vis[v] = i;  
                v = pre[v];  
            }  
            if(v != root && id[v] == -1)//??  
            {  
                for(int u = pre[v]; u != v; u = pre[u]) id[u] = cnt;  
                id[v] = cnt++;  
            }  
        }  
        if(cnt == 0) break; //??   ?break  
        for(int i = 0; i < V; i++)  
            if(id[i] == -1) id[i] = cnt++;  
              //3.????  
        for(int i = 0; i < E; i++)  
        {  
            int u = edge[i].u;  
            int v = edge[i].v;  
            edge[i].u = id[u];  
            edge[i].v = id[v];  
            if(id[u] != id[v]) edge[i].w -= in[v];  
        }  
        V = cnt;  
        root = id[root];  
    }  
    return ret;  
} 
int zu,xs[10005],ys[10005],zs[10005];
int main()  
{  
//	freopen("1009.in","r",stdin);
//	freopen("1009.out","w",stdout);
	scanf("%d",&zu);
    for(;zu;--zu)
    {  
    	scanf("%d%d", &n, &m);
        for(int i = 0; i < m; i++)  
        {  
            scanf("%d%d%d", &edge[i].u, &edge[i].v, &edge[i].w);  
            edge[i].u--;  
            edge[i].v--;  
            edge[i].w*=1000;
            if(edge[i].v==n-1){
            	edge[i].w+=(999-edge[i].u);
            }
            edge[i].w=-edge[i].w;
            xs[i]=edge[i].u;
            ys[i]=edge[i].v;
            zs[i]=edge[i].w;
            if(edge[i].u == edge[i].v){
            	edge[i].w = INF; 
            	zs[i] = INF;
            }
        }  
        int ans = Directed_MST(0, n, m);  
        printf("%d %d\n",(-ans)/1000,1000-(-ans)%1000);
    }  
    return 0;  
}  

【朱-刘算法】【最小树形图】hdu6141 I am your Father!

标签:cst   tle   eof   nod   using   网上   cstring   ace   ems   

原文地址:http://www.cnblogs.com/autsky-jadek/p/7385095.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!