HDU 4786 最小生成树变形 kruscal(13成都区域赛F)

Fibonacci Tree

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 4136    Accepted Submission(s): 1283

Problem Description

  Coach Pang is interested in Fibonacci numbers while Uncle Yang wants him to do some research on Spanning Tree. So Coach Pang decides to solve the following problem:
  Consider a bidirectional graph G with N vertices and M edges. All edges are painted into either white or black. Can we find a Spanning Tree with some positive Fibonacci number of white edges?
(Fibonacci number is defined as 1, 2, 3, 5, 8, ... )

Input

  The first line of the input contains an integer T, the number of test cases.
  For each test case, the first line contains two integers N(1 <= N <= 105) and M(0 <= M <= 105).
  Then M lines follow, each contains three integers u, v (1 <= u,v <= N, u<> v) and c (0 <= c <= 1), indicating an edge between u and v with a color c (1 for white and 0 for black).

Output

  For each test case, output a line “Case #x: s”. x is the case number and s is either “Yes” or “No” (without quotes) representing the answer to the problem.

Sample Input

2

4 4

1 2 1

2 3 1

3 4 1

1 4 0

5 6

1 2 1

1 3 1

1 4 1

1 5 1

3 5 1

4 2 1

Sample Output

Case #1: Yes

Case #2: No

Source

2013 Asia Chengdu Regional Contest

题意:N个顶点,M条边,每条边或为白色或为黑色( 1 or 0 ),问有没有用是斐波那契数的数目的白色边构成一棵生成树

题解:N个顶点构成的生成树有N-1条边 ,首先判断能否能构成生成树,图是否是联通的,无法构成则输出No

先使用所有的黑边 不断加边,看最多能使用多少条黑边使得不形成环 求得白边的使用的数量的下界

然后再使用所有的白边,不断的加边,看最多能使用多少条白边使得不形成环,求得白边使用的数量的上界

然后是否存在斐波那契数载这个区间

我们等于是要证明对于所有在min和max之间的白边数我们都能够达到。

考虑从最小的min开始,我总可以找到一条黑边,使得将它去掉在补上一条白边保持图联通。为什么呢,如果在某一个状态(设白边数为x)下,不存在一条黑边可以被白边代替,那么现在我们把所有黑边去掉,剩下x条白边,那我们知道,x一定等于max,因为若x<max,那么我们在算max的那个步骤中,先将这x条白边加入,还可以在加入max-x条白边使得不存在环,那么这与没有一条黑边可以被白边代替矛盾,所以这就证明了从min到max我都可以达到

  1 #include<iostream>
  2 #include<cstring>
  3 #include<cstdio>
  4 using namespace std;
  5 struct node
  6 {
  7     int u,v,c;
  8 } N[100005];
  9 int fib[50];
 10 int fa[100005];
 11 int t;
 12 int n,m;
 13 int coun;
 14 int find(int root)
 15 {
 16     if(root==fa[root])
 17         return root;
 18     else
 19         return fa[root]=find(fa[root]);
 20 }
 21 void unin(int a,int b)
 22 {
 23     int aa=find(a);
 24     int bb=find(b);
 25     if(aa!=bb)
 26         fa[aa]=bb;
 27 }
 28 void init()
 29 {
 30     for(int i=1; i<=n; i++)
 31         fa[i]=i;
 32 }
 33 void fi()
 34 {
 35     fib[1]=1;
 36     fib[2]=2;
 37     for(int i=3;; i++)
 38     {
 39         fib[i]=fib[i-1]+fib[i-2];
 40         if(fib[i]>100005)
 41         {
 42             coun=i;
 43             break;
 44         }
 45     }
 46 }
 47 int kruscal(int exm)
 48 {
 49     init();
 50     int k=0;
 51     for(int i=1; i<=m; i++)
 52     {
 53         if(N[i].c!=exm)
 54         {
 55             if(find(N[i].u)!=find(N[i].v))
 56             {
 57                 k++;
 58                 unin(N[i].u,N[i].v);
 59             }
 60         }
 61     }
 62     return k;
 63 }
 64 int main()
 65 {
 66     fi();
 67     while(scanf("%d",&t)!=EOF)
 68     {
 69         for(int j=1; j<=t; j++)
 70         {
 71             scanf("%d %d",&n,&m);
 72             for(int i=1; i<=m; i++)
 73             scanf("%d %d %d",&N[i].u,&N[i].v,&N[i].c);
 74             printf("Case #%d: ",j);
 75             int zha;
 76             zha=kruscal(2);//可以使用白边和黑边
 77             if(zha!=(n-1))//判环
 78             {
 79                 printf("No\n");
 80                 continue;
 81             }
 82             int l=n-1-kruscal(1);//构成生成树的白边数量的下限
 83             int r=kruscal(0);// 构成生成树的白边数量的上限
 84             int flag=0;
 85             for(int i=1; i<coun; i++)//判断是否存在满足条件的fib
 86             {
 87                 if(fib[i]>=l&&fib[i]<=r)
 88                 {
 89                     printf("Yes\n");
 90                     flag=1;
 91                     break;
 92
 93                 }
 94             }
 95             if(flag==0)
 96                 printf("No\n");
 97         }
 98     }
 99     return 0;
100 }
时间: 2024-11-10 15:07:42

HDU 4786 最小生成树变形 kruscal(13成都区域赛F)的相关文章

13杭州区域赛现场赛Rabbit Kingdom(树状数组+离线)

题意:给你一个长度数列,再给你m个询问(一个区间),问你在这个区间里面有多少个数与其他的数都互质. 解题思路:你看这种类型的题目都可以肯定这是 离线+树状数组(线段树).主要就是他的更新信息.这里我的处理是先把1-200000(每个数的范围)数里面所有的质因子求出来.然后从后往前遍历数组.会出现以下几种情况 1.a[k]的质因子在后面出现过而[更新标记] 和[被更新标记] 都为假 2.a[k]的质因子在后面出现过的那个位置 I   [更新标记]为 真 . 3.a[k]的质因子在后面出现过且那个位

36th成都区域赛网络赛 hdoj4039 The Social Network(建图+字符串处理)

这题是某年成都区域赛网络赛的一题. 这题思路非常easy,可是从时间上考虑,不妨不要用矩阵存储,我用的链式前向星. 採用线上查询.利用map对字符串编号,由于非常方便.要推荐的朋友,事实上就是朋友的朋友(这里指的是直接朋友,图中即指有直接边相连的). 所以在寻找时,仅仅须要查找朋友的朋友,并计数. 注意:在输出时不能有对于的空格. 附代码: #include<iostream> using namespace std; #include<cstdio> #include<cs

HDU 4786 Fibonacci Tree (2013成都1006题) 最小生成树+斐波那契

题意:问生成树里能不能有符合菲波那切数的白边数量 思路:白边 黑边各优先排序求最小生成树,并统计白边在两种情况下数目,最后判断这个区间就可以.注意最初不连通就不行. 1 #include <stdio.h> 2 #include <algorithm> 3 #include <string.h> 4 #include<cmath> 5 #define LL long long 6 using namespace std; 7 int t,n,m; 8 int

hdu 1598(最小生成树变形)

解题思路:这道题我一开始的思路是动规,dp_max[i][j]表示i-j的最大边,dp_min[i][j]表示i-j的最小边,可是这样会有问题,有可能最大边与最小边不在同一条路径上,这样就很麻烦了. 正解:参考了网上的思路,这里其实是最小生成树的变形.由于是最大边与最小边的差最小,可以先把所有边按从小到大排好序,接着就是kruskal的思路了,我们把边从小到大以此加入进去,如果start和end之间有通路,那么就说明找到了一条满足要求的路径了.注意,这里由于最小边暂时是未知的,我们应该还要先去枚

HDU 6229 Wandering Robots(2017 沈阳区域赛 M题,结论)

题目链接  HDU 6229 题意 在一个$N * N$的格子矩阵里,有一个机器人. 格子按照行和列标号,左上角的坐标为$(0, 0)$,右下角的坐标为$(N - 1, N - 1)$ 有一个机器人,初始位置为$(0, 0)$. 现在这个矩阵里面,有一些障碍物,也就是说机器人不能通过这些障碍物. 若机器人当前位置为$(x, y)$,那么他下一个位置有可能为与当前格子曼哈顿距离为$1$的所有格子的任意1个. 也有可能停留在原来的位置$(x, y)$ 求经过无限长的时间之后,这个机器人的位置在给定区

hdu 5023 线段树 区间 2014广东区域赛网赛

http://acm.hdu.edu.cn/showproblem.php?pid=5023 当时大一学弟15minAC 搞得我压力山大 给队友写了 今天重新做了下,题还是很水  但是因为pushdown的时候if(l==r)return没有写  WA了一次 感觉到现在,简单的线段树已经可以随意点写了,就是按照自己的理解写,别慌,错了按树的结构思考下重新写 查询不知道pushdown所有的会不会超时,我的还是区间的查询,凡是子区间被修改过的结点,该节点pushdown后 其co值都被我改为0 然

hdu 5078 Osu! (2014 acm 亚洲区域赛鞍山 I)

题目链接:http://acm.hdu.edu.cn/showproblem.php? pid=5078 Osu! Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others) Total Submission(s): 180    Accepted Submission(s): 114 Special Judge Problem Description Osu! is a very p

13南京区域赛现场赛 题目重演 解题报告

A.GPA(HDU4802): 纯属进入状态用,给你一些字符串对应的权重,求加权平均,如果是N,P不计入统计 GPA Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 1193    Accepted Submission(s): 743 Problem Description In college, a student may take

HDU 5074 Hatsune Miku(14鞍山区域赛 E)DP

题意:给定一个序列 有些位数未知,给你如果两个数连续所得到的能量,问你怎么安排数字使得总能量最大 解题思路:dp,只与上一个字母有关. 解题代码: 1 // File Name: e.cpp 2 // Author: darkdream 3 // Created Time: 2014年10月22日 星期三 12时16分10秒 4 5 #include<vector> 6 #include<list> 7 #include<map> 8 #include<set&g