Matrix(类似kruskal)

Matrix

Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 32768/32768K (Java/Other)
Total Submission(s) : 2   Accepted Submission(s) : 1

Problem Description

Machines have once again attacked the kingdom of Xions. The kingdom of Xions has N cities and N-1 bidirectional roads. The road network is such that there is a
unique path between any pair of cities.

Morpheus has the news that K Machines are planning to destroy the whole kingdom. These Machines are initially living in K different cities of the kingdom and
anytime from now they can plan and launch an attack. So he has asked Neo to destroy some of the roads to disrupt the connection among Machines. i.e after destroying those roads there should not be any path between any two Machines.

Since the attack can be at any time from now, Neo has to do this task as fast as possible. Each road in the kingdom takes certain time to get destroyed and they
can be destroyed only one at a time.

You need to write a program that tells Neo the minimum amount of time he will require to disrupt the connection among machines.

Input

The first line is an integer T represents there are T test cases. (0

Output

For each test case print the minimum time required to disrupt the connection among Machines.

Sample Input

1 5 3 2 1 8 1 0 5 2 4 5 1 3 4 2 4 0

Sample Output

10

题解:这题就是一些机器人在不同城市,通过毁坏一定的路,使他们不能相互联系;毁坏路需要时间,求最短时间;

解这个题需要先对时间从大到小排序,从大到小是为了让那些没被标记的陷进去,到最后出现被标记的路时就小了,所需时间就少了;

注意的是vis的记录,还有要让被标记的当老大;

代码:

 1 #include<stdio.h>
 2 #include<string.h>
 3 #include<algorithm>
 4 using namespace std;
 5 const int MAXN=100010;
 6 struct Node{
 7     int s,e,t;
 8 };
 9 Node dt[MAXN];
10 /*int cmp(const void *a,const void *b){
11     return (*(Node *)a).t-(*(Node *)b).t)  ;//
12 }*/
13 int cmp(Node a,Node b){
14     return a.t>b.t;
15 }
16 int pre[MAXN];
17 int find(int x){
18     return pre[x]= x==pre[x]?x:find(pre[x]);
19 }
20 int visit[MAXN],n,m,flot;
21 __int64 time;
22 void initial(){
23     memset(visit,0,sizeof(visit));
24     memset(pre,-1,sizeof(pre));
25     time=0;flot=0;
26 }
27 void merge(Node a){
28     int f1,f2;
29     if(pre[a.s]==-1)pre[a.s]=a.s;
30     if(pre[a.e]==-1)pre[a.e]=a.e;
31     f1=find(a.s);f2=find(a.e);
32     if(f1==f2)return;
33     if(visit[f1]&&visit[f2]){
34         time+=a.t;
35         flot++;
36     //    printf("%d %d\n",a.s,a.e);
37     }
38     else if(f1!=f2){
39         if(visit[f1])pre[f2]=f1;
40         else pre[f1]=f2;
41     }
42 }
43 int main(){
44     int T,temp;
45     scanf("%d",&T);
46         while(T--){
47             initial();
48             scanf("%d%d",&n,&m);
49             for(int i=0;i<n-1;i++){
50                 scanf("%d%d%d",&dt[i].s,&dt[i].e,&dt[i].t);
51             }
52             ///qsort(dt,n-1,sizeof(dt[0]),cmp);
53             sort(dt,dt+n-1,cmp);
54             for(int i=0;i<m;i++){
55                 scanf("%d",&temp);
56                 visit[temp]=1;
57             }
58             for(int i=0;i<n-1;i++){
59                 merge(dt[i]);
60                 if(flot==m-1)break;
61             }
62             printf("%I64d\n",time);
63         }
64     return 0;
65 }
时间: 2024-10-05 05:31:55

Matrix(类似kruskal)的相关文章

【LeetCode】Spiral Matrix II

Given an integer n, generate a square matrix filled with elements from 1 to n2 in spiral order. For example,Given n = 3, You should return the following matrix: [ [ 1, 2, 3 ], [ 8, 9, 4 ], [ 7, 6, 5 ] ]此题与Spiral Matrix类似,可以用相同的方法解决,相比之下,此题比前一题简单 publ

LeetCode: Spiral Matrix II 解题报告-三种方法解决旋转矩阵问题

Spiral Matrix IIGiven an integer n, generate a square matrix filled with elements from 1 to n2 in spiral order. For example,Given n = 3, You should return the following matrix:[ [ 1, 2, 3 ], [ 8, 9, 4 ], [ 7, 6, 5 ]] SOLUTION 1: 还是与上一题Spiral Matrix类似

2017多校Round4(hdu6067~hdu6079)

补题进度:10/13 1001 待填坑 1002(kmp+递推) 题意: 有长度为n(<=50000)的字符串S和长度为m(m<=100)的字符串T,有k(k<=50000)组询问,每个询问(L,R),表示对于所有的(i,j)(1<=i<=L,R<=j<=n),将S[1..i]和S[j..n]拼接起来,求这个新的S'中出现T的次数总和 分析: 我们分析对于一个(i,j)的情况下,那么T的出现有三种情况,一种是整体在[1..i],第二种是整体在[j..n],第三种是

[CF#250 Div.2 D]The Child and Zoo(并查集)

题目:http://codeforces.com/problemset/problem/437/D 题意:有n个点,m条边的无向图,保证所有点都能互通,n,m<=10^5 每个点都有权值,每条边的权值定义为这条边连接两点的权值中的最小值. f(p,q)表示p到q的路径中边权的最小值,如果有多条路经,就取每条路径最小值中的最小值 要求的就是对于所有1<=p<=n,1<=q<=n,p≠q,f(p,q)的平均值 分析: 刚开始是想考虑每条边对总和的贡献,结果没想通. 一个很巧的办法

zoj 3659 第37届ACM/ICPC 长春赛区现场赛E题 (并查集)

题意:给出一棵树,找出一个点,求出所有点到这个点的权值和最大,权值为路径上所有边权的最小值. 用神奇的并查集,把路按照权值从大到小排序,然后用类似Kruskal的方法不断的加入边. 对于要加入的一条路,这条路连接这城市x和y,x所在的集合为A, y所在的集合为B, 可以确定A,B集合内的所有路都比当前这条路的权值大.如果让集合B加入集合A,就是让中心城市位于集合A,那么可以确定这两个集合合并之后的总权值为: A的权值总和+B的数量*当前这条路的权值.同样算出让集合B加入集合A的情况,取两者合并后

hdu5441(2015长春赛区网络赛1005)类最小生成树、并查集

题意:有一张无向图,一些点之间有有权边,某条路径的值等于路径上所有边的边权的最大值,而某个点对的值为这两点间所有路径的值的最小值,给出多个询问,每个询问有一个值,询问有多少点对满足其值小于等于询问值.点的顺序不同算作不同点对. 这题的做法很类似Kruskal算法.一开始所有的点都为一个并查集,从权值最小的边开始,当加入这条边的时候,这条边连接的两个点(并查集)之间相互到达的路径中,值最小的一个路径一定就是通过这条边的,所以这两点间的值就是这条边的权值.之后每加入一条最小边,如果可以用来合并两个并

Codeforces Round #270 D C B A

谈论最激烈的莫过于D题了! 看过的两种做法不得不ORZ,特别第二种,简直神一样!!!!! 1th:构造最小生成树. 我们提取所有的边出来按边排序,因为每次我们知道边的权值>0, 之后每次把边加入集合中,不断构造,类似  kruskal算法,构造出边后 再对每个点进行整张图的DFS求距离 复杂度O(N^2lgN):对所有边排序的复杂度. 1 #include<bits/stdc++.h> 2 3 #define N 2222 4 using namespace std; 5 typedef

求一个指定点对的路径上的最大边权或最小边权

dij贪心地取min(cur,pre)最大的路径 或者直接按权值排序,贪心地从最小或最大取,并茶几加点,联通停止即可... 我们还可以用二分..就是二分最大边权或者最小边权..重复上面类似kruskal的过程 k短路..次小生成树..可持久化堆 dij本质还是个贪心地过程 求满足某条件的最短路径或最长路径,如果该条件满足可以筛出的满足某性质的点中可形成的路径解集中包含题目所有的答案 我们就可以先用BFS等手段先把点筛出来..然后在这些点中跑各种路径算法 对于最短路径我们可以考察是否有负环..对于

UVA 1664 Conquer a New Region

题意:在一颗树上要求一个到其他结点容量和最大的点,i,j之前的容量定义为i到j的路径上的最小边容量. 一开始想过由小到大的去分割边,但是很难实现,其实换个顺序就很容易做了,类似kruskal的一个贪心算法, 从大到小的连边,每次连通两个分量A和B,这样可以新边容量一定是两个分量相互到达的最小容量,其余边一定选最大,满足最优子结构 而且使新的连通分量取得最大值一定在其中一边,两者中选其中一者即可.具体实现用并查集维护即可. #include<bits/stdc++.h> using namesp