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 #define maxm 10010
 8 #define inf 0x7f7f7f7f
 9 using namespace std;
10 int n,m,cnt,sum,mr,tot,rec;
11 struct hh{
12     int u,v,d;
13 }b[maxm*3];
14 int in[maxm],pre[maxm],col[maxm],id[maxm];
15 int zl(int root,int p){
16     rec=0;//一定 !!!不能!!!!定义到!!!!里面去!!!!!!
17     while (1){
18         for (int i=0;i<=p;++i) in[i]=inf;
19         memset(pre,-1,sizeof(pre));//可能涉及到零 所以每个数组都初始化为-1
20         for (int i=1;i<=cnt;++i){
21             int x=b[i].u,y=b[i].v,z=b[i].d;
22             if (z<in[y]&&x!=y){
23                 pre[y]=x;
24                 in[y]=z;
25                 if (x==root) mr=i;
26             }
27         }
28         tot=0;
29         memset(id,-1,sizeof(id));
30         memset(col,-1,sizeof(col));
31         in[root]=0;
32         for (int i=0;i<=p;++i){
33             rec+=in[i];
34             int j=i;
35             while (j!=root&&col[j]!=i&&id[j]==-1) col[j]=i,j=pre[j];
36             if (j!=root&&id[j]==-1){
37                 for (int q=pre[j];q!=j;q=pre[q]) id[q]=tot;
38                 id[j]=tot++;
39             }
40         }
41         if (tot==0) break;
42         for (int i=0;i<=p;++i) if (id[i]==-1) id[i]=tot++;
43         for (int i=1;i<=cnt;++i){
44             int x=b[i].u,y=b[i].v;
45             b[i].u=id[x];
46             b[i].v=id[y];
47             if (b[i].u!=b[i].v) b[i].d-=in[y];
48         }
49         p=tot-1;
50         root=id[root];
51     }
52     return rec;
53 }
54 int main(){
55     while (scanf ("%d%d",&n,&m)!=EOF){
56         memset(b,-1,sizeof(b));
57         cnt=0,sum=0;
58         for (int i=1;i<=m;++i){
59             int x,y,z;
60             scanf ("%d%d%d",&x,&y,&z);
61             b[++cnt].u=x+1,b[cnt].v=y+1,b[cnt].d=z;
62             sum+=z;
63         }
64         sum++;
65         for (int i=1;i<=n;++i) b[++cnt].u=0,b[cnt].v=i,b[cnt].d=sum;
66         int ans=zl(0,n);
67         if (ans>=2*sum) printf("impossible\n\n");
68         else printf("%d %d\n\n",ans-sum,mr-m-1);
69     }
70     return 0;
71   }

学过的人都知道是朱刘算法 如果没有了解的话推荐blog http://blog.csdn.net/l123012013048/article/details/48375819

以及度娘也讲得比较清楚 如果光看解释看不懂 还是应该多写写画画 再跟着代码理解一下

这里就不赘述了其实我也并不怎么太懂

解释下几个关键点

1.这题出来之后很容易就发现 它跟正常求最小生成树有一点很重要的不同 ——没有固定的根 

那这就很尴尬了 但是自己动手丰衣足食 没有根的话大不了造一个吧

好 那就造一个0 并且把他跟图里的所有点都连下边吧(注意!原题中可能出现编号为0的点 为了不冲突 输入时进行加1操作(结束输出时会-1

2.然后这个点我们连边的时候权值是sum+1 因为如果它只给你点而不给你边的时候是无法把这种不合法情况判出来的!

记住 这个时候 sum已经加1了!

3.接着就是板子式的zl算法 出来之后————————!!!

判impossible的时候到了! 接下来我们可以用到之前的sum了 因为图中应该只有一个入度为0即直连虚根的点所以 ans最大不会超过sum(已加1)*2

好的 这题就写完了qwq 反正我是挂在把rec定义到了while里面所以狂wa5遍QAQ

这应该是我写过最神经的题解了qwq

时间: 2024-08-07 16:22:37

hdu 2121 Ice_cream’s world II的相关文章

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(无定根最小树形图)

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 最小树形图

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

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

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

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 【无根节点最小树形图】

题目:hdoj 2121 Ice_cream's world II 题意:题目是一道躶题,给n个点,m条边的有向图,然后找一个点,到所有点的距离和最小,找出这个点并输入距离. 分析:很明显是求一个最小树形图,但是没有说根节点,要找跟节点,我们可以虚拟一个节 点 x ,x 到所有节点连边距离为前面所有距离和+1为 dis . 然后从x 节点求一次最小树形图为ans,则ans - dis 就是最小树形图的距离. 如果图不连通,或者ans>=2*dis 说明不存在,都则与 x 点出发的边就是结果点 A

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

HDU2121 Ice_cream’s world II —— 最小树形图 + 超级点

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2121 Ice_cream's world II Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 5832    Accepted Submission(s): 1493 Problem Description After awarded la

hdu 1207 汉诺塔II (DP+递推)

汉诺塔II Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 4529    Accepted Submission(s): 2231 Problem Description 经典的汉诺塔问题经常作为一个递归的经典例题存在.可能有人并不知道汉诺塔问题的典故.汉诺塔来源于印度传说的一个故事,上帝创造世界时作了三根金刚石柱子,在一根柱子上从下往