hdoj 2121 Ice_cream’s world II 【无根节点最小树形图】

题目:hdoj 2121 Ice_cream’s world II

题意:题目是一道躶题,给n个点,m条边的有向图,然后找一个点,到所有点的距离和最小,找出这个点并输入距离。

分析:很明显是求一个最小树形图,但是没有说根节点,要找跟节点,我们可以虚拟一个节 点 x ,x 到所有节点连边距离为前面所有距离和+1为 dis 。

然后从x 节点求一次最小树形图为ans,则ans - dis 就是最小树形图的距离。

如果图不连通,或者ans》=2*dis 说明不存在,都则与 x 点出发的边就是结果点

AC代码:

#include <iostream>
#include <algorithm>
#include <string>
#include <math.h>
#include <vector>
#include <cstring>
#include <cstdio>
using namespace std;
const int N = 1100;
const int inf = 0x3f3f3f3f;
int n,m;
struct Node
{
    int from,to,dis;
};
vector<Node> e;
int ha[N],vis[N],father[N],in[N];
int Minroot;
int zhuliu(int root)
{
    int ans = 0;
    while(true)
    {
        for(int i=0;i<n;i++)
            in[i] = inf;
        memset(father,-1,sizeof(father));
        for(int i=0; i<e.size(); i++) //找最小入边
        {
            int to = e[i].to;
            if(e[i].dis<in[to] && e[i].from!=e[i].to)
            {
                in[to] = e[i].dis;
                father[to] = e[i].from;
                if(e[i].from == root) //找最小
                    Minroot = i;
            }
        }
        for(int i=0;i<n;i++)
        {//printf("%d ",in[i]);
            if(i!=root && in[i]==inf)
                return -1;
        }
        int cnt = 0;
        in[root] = 0;
        memset(ha,-1,sizeof(ha));
        memset(vis,-1,sizeof(vis));
        for(int i=0;i<n;i++) //找自环
        {

            ans += in[i];
            int v = i;
            while(v!=root && ha[v]==-1 && vis[v]!=i)
            {
                vis[v] = i;
                v = father[v];
            }
            if(v!=root && ha[v]==-1)
            {
                for(int j = father[v];j != v;j=father[j])
                {
                    ha[j] = cnt;
                }
                ha[v] = cnt++;
            }
        }
        if(cnt == 0) //跳出条件
            break;
        for(int i=0;i<n;i++)
            if(ha[i]==-1)
                ha[i]=cnt++;
        for(int i = 0; i< e.size();i++)
        {
            int tmp = e[i].to;
            e[i].from = ha[e[i].from];
            e[i].to = ha[e[i].to];
            if(e[i].from != e[i].to)
                e[i].dis -= in[tmp];
        }
        n = cnt;
        root = ha[root];
    }
    return ans;
}
int main()
{
    //freopen("Input.txt","r",stdin);
    while(~scanf("%d%d",&n,&m))
    {
        int num = 0;
        for(int i=0;i<m;i++)
        {
            int x,y,s;
            scanf("%d%d%d",&x,&y,&s);
            e.push_back((Node){x,y,s});
            num = num + s;
        }
        num++;
        for(int i=0;i<n;i++)
            e.push_back((Node){n,i,num});
        n++;
        int ans = zhuliu(n-1);
        //printf("%d %d\n",ans,num);
         if(ans==-1||ans>=2*num)
            puts("impossible");
        else
            printf("%d %d\n",ans-num,Minroot-m);
        puts("");
        e.clear();
    }
    return 0;
}
时间: 2024-11-07 04:03:25

hdoj 2121 Ice_cream’s world II 【无根节点最小树形图】的相关文章

hdoj 2121 Ice_cream’s world II 【没有最低树的根节点】

称号:pid=2121" target="_blank">hdoj 2121 Ice_cream's world II 题意:题目是一道躶题,给n个点,m条边的有向图.然后找一个点.到全部点的距离和最小.找出这个点并输入距离. 分析:非常明显是求一个最小树形图,可是没有说根节点.要找跟节点,我们能够虚拟一个节 点 x .x 到全部节点连边距离为前面全部距离和+1为 dis . 然后从x 节点求一次最小树形图为ans,则ans - dis 就是最小树形图的距离. 假设图不

HDOJ 2121 Ice_cream’s world II 最小树形图无根树

朱刘算法 最小树形图无根树: 建立一个虚拟的根节点,向所有节点连边,权值为其他所有边的权值和+1 在求最小树形图的时候,记录和虚拟的根相连的是哪个节点 在这题中,边是从小往大加的所以直接记录的是相连的是第几号边.... Ice_cream's world II Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 3442    Accept

HDU 2121 Ice_cream’s world II(无定根最小树形图)

Ice_cream’s world II Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 3115    Accepted Submission(s): 737 Problem Description After awarded lands to ACMers, the queen want to choose a city be her

HDU 2121 Ice_cream’s world II (不定根最小树形图)

题目地址:HDU 2121 这题没有给定根.最容易想到的当然是暴力,枚举所有的根,但是TLE是显然的..为了处理不定根的情况,可以虚拟一个根,然后用这个根去跟所有的点连边,权值为其他所有权值的和+1,目的是防止成为最小树形图的一条边.然后跑出最小树形图后,那么这个虚拟根肯定跟一个实际根相连,这时候根就找到了,然后再在最终的总花费中减去虚拟的那条边的权值就可以了. 代码如下: #include <iostream> #include <string.h> #include <m

HDU 2121 Ice_cream’s world II 最小树形图

这个题就是需要求整个有向带权图的最小树形图,没有指定根,那就需要加一个虚根 这个虚根到每个点的权值是总权值+1,然后就可以求了,如果求出来的权值大于等于二倍的总权值,就无解 有解的情况,还需要输出最根,多解的情况,肯定是某个环上所有的点为根都可以(比如所有的点构成一个环), 这样加边的时候虚边的时候按照点的标号从小到大编,这样第一个以虚根为前驱的点也是最小的点就可以标记(标记一下) #include <iostream> #include <algorithm> #include

hdu 2121 Ice_cream’s world II

真的是一下午都砸在这题上了 不对 是从上午10点到现在都砸掉了 啊啊啊啊啊啊啊啊我有毒吧!!!!!!! 我真的是不想再看到这道题了 卡了电脑3遍啊啊啊啊啊为什么!!!!! 生无可恋脸 1 #include<iostream> 2 #include<cstdio> 3 #include<cstdlib> 4 #include<cstring> 5 #include<algorithm> 6 #include<string> 7 #def

HDU - 2121 Ice_cream’s world II(朱刘算法+虚根)

题目大意:给你N个点,M条有向边,问以哪个点为根结点时,能使最小生成树总权值达到最小,输出总权值和根. 如果构不成最小生成树,另外输出 解题思路:这题很巧妙,暴力枚举的话,肯定TLE,所以,这题就需要点技巧了 可以设一个虚根,虚根连接每一个点,权值为所有边的总权值+1.接着,以虚根为根,跑朱刘算法. 跑出结果后,要判断一下,如果最小生成树的总权值比2 * (所有边的总权值+1)还要大,表示虚根至少和两个点相连了,这样最小生成树就是棵假的最小生成树了,因为至少有两个点入度为0了 得到结果时要怎么找

hdu2121 Ice_cream’s world II 最小树形图(难)

这题比HDU4009要难一些.做了4009,大概知道了最小树形图的解法.拿到这题,最直接的想法是暴力.n个点试过去,每个都拿来做一次根.最后WA了,估计是超时了.(很多题都是TLE说WA,不断修改代码也看不出来错哪了). 网上的正解是添加一个虚拟根(树根),使得它与n个点都有边相连.HDU4009题这样得到的边有实际的意义,好理解.这题这样得到的边不好理解,并且边权应该是多少也有讲究.别人的解题报告中是把这些边的权值设为原本所有边的权值之和加1.这样做的目的,是为了完全把这些边与原本的边区分开.

HDU2121 Ice_cream’s world II 【最小树形图】+【不定根】

Ice_cream's world II Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 2744    Accepted Submission(s): 630 Problem Description After awarded lands to ACMers, the queen want to choose a city be he