• HDU 6141 I am your Father!(最小树形图+权值编码)


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

    题意:

    求最大树形图。

     

    思路:

    把边的权值变为负值,那么这就是个最小树形图了,直接套模板就可以解决。

    有个问题就是n结点的父亲结点的编号要尽量小,这里有个技巧可以用,权值编码,将所有边的权值都放大1000倍,对于和n相连的边,每条边在减去(n-u)的权值。这样就会去优先考虑编号小的边,而且因为权值最大为100,所以扩大1000是不会影响结果的。

      1 #include<iostream>
      2 #include<algorithm>
      3 #include<cstring>
      4 #include<cstdio>
      5 #include<sstream>
      6 #include<vector>
      7 #include<stack>
      8 #include<queue>
      9 #include<cmath>
     10 #include<map>
     11 #include<set>
     12 using namespace std;
     13 typedef long long ll;
     14 typedef pair<int,ll> pll;
     15 const int inf = 0x3f3f3f3f;
     16 const int maxn=1000+5;
     17 const int mod=1e9+7;
     18 
     19 int n, m;
     20 
     21 struct node
     22 {
     23     int u,v,w;
     24 }edge[10*maxn];
     25 
     26 int pre[maxn],id[maxn],use[maxn];
     27 int in[maxn];
     28 
     29 int mini_tree(int root,int n,int m)//分别是树根,节点数,边数,序号从1开始
     30 {
     31     int ans=0;
     32     int u;
     33     while(true)
     34     {
     35         for(int i=1;i<=n;i++)  in[i]=inf;
     36         for(int i=1;i<=m;i++)
     37         {
     38             int u=edge[i].u;
     39             int v=edge[i].v;
     40             if(edge[i].w<in[v]&&u!=v)
     41             {
     42                 in[v]=edge[i].w;
     43                 pre[v]=u;
     44             }
     45         }//找最小的入边
     46         for(int i=1;i<=n;i++)
     47         {
     48             if(i==root)continue;
     49             ans+=in[i];//把边权加起来
     50             if(in[i]==inf)//如果存在没有入弧的点则不存在最小树形图
     51                 return -1;
     52         }
     53         memset(id,-1,sizeof(id));
     54         memset(use,-1,sizeof(use));
     55         int cnt=0;
     56         for(int i=1;i<=n;i++)//枚举每个点,搜索找环
     57         {
     58             int v=i;
     59             while(v!=root&&use[v]!=i&&id[v]==-1)
     60             {
     61                 use[v]=i;
     62                 v=pre[v];
     63             }
     64             if(v!=root&&id[v]==-1)//当找到环的时候缩点编号
     65             {
     66                 ++cnt;
     67                 id[v]=cnt;
     68                 for(u=pre[v];u!=v;u=pre[u])
     69                     id[u]=cnt;
     70             }
     71         }
     72         if(cnt==0)//如果没有环结束程序
     73             break;
     74         for(int i=1;i<=n;i++)//把余下的不在环里的点编号
     75             if(id[i]==-1)
     76                 id[i]=++cnt;
     77         for(int i=1;i<=m;i++)//建立新的图
     78         {
     79             int u=edge[i].u;
     80             int v=edge[i].v;
     81             edge[i].u=id[u];
     82             edge[i].v=id[v];
     83             if(edge[i].u!=edge[i].v)
     84                 edge[i].w-=in[v];
     85         }
     86         n=cnt;//更新节点数和根节点的编号
     87         root=id[root];
     88     }
     89     return ans;
     90 }
     91 
     92 int main()
     93 {
     94     //freopen("in.txt","r",stdin);
     95     int T;
     96     scanf("%d",&T);
     97     while(T--)
     98     {
     99         scanf("%d%d",&n,&m);
    100         for(int i=1;i<=m;i++)
    101         {
    102             int u,v,w;
    103             scanf("%d%d%d",&u,&v,&w);
    104             w*=-1000;
    105             if(v==n)  w-=(n-u);
    106             edge[i].u=u, edge[i].v=v, edge[i].w=w;
    107         }
    108         int ans=mini_tree(1,n,m);
    109         printf("%d %d
    ",-ans/1000,n-(-ans)%1000);
    110     }
    111     return 0;
    112 }
  • 相关阅读:
    absorb|state|
    confessed to doing|conform|confined|entitle|
    relieved|auction|calculate|campaign|charge for |chartered
    worship|spurs|drowns out|frauds|expell|spray with|deposit|moist|gave a sigh
    discount the possibility|pessimistic|bankrupt|
    every|each|the用于姓氏的复数形式|comrades-in-arms|clothes are|word|steel|affect|effect
    Measures of Center
    2020年会分享
    source insight 4.0的基本使用方法
    opencv doc学习计划
  • 原文地址:https://www.cnblogs.com/zyb993963526/p/7390906.html
Copyright © 2020-2023  润新知