Connect the Cities

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 7338    Accepted Submission(s): 2093

Problem Description
In 2100, since the sea level rise, most of the cities disappear. Though some survived cities are still connected with others, but most of them become disconnected. The government wants to build some roads to connect all of these cities again, but they don’t want to take too much money. 
 
Input
The first line contains the number of test cases. Each test case starts with three integers: n, m and k. n (3 <= n <=500) stands for the number of survived cities, m (0 <= m <= 25000) stands for the number of roads you can choose to connect the cities and k (0 <= k <= 100) stands for the number of still connected cities. To make it easy, the cities are signed from 1 to n. Then follow m lines, each contains three integers p, q and c (0 <= c <= 1000), means it takes c to connect p and q. Then follow k lines, each line starts with an integer t (2 <= t <= n) stands for the number of this connected cities. Then t integers follow stands for the id of these cities.
 
Output
For each case, output the least money you need to take, if it’s impossible, just output -1.
 
Sample Input
1
6 4 3
1 4 2
2 6 1
2 3 5
3 4 33
2 1 2
2 1 3
3 4 5 6
 
Sample Output
1
 
 
这道题我的思路是:先处理k个数,然后再用并查集求剩下没连通的。之前要排序,最后检查是否连通。。。。
 
╮(╯▽╰)╭  自己超时了好多次,还有就是,题意马虎了,又WA了几次,,,悲剧。
 
#include <iostream>
#include <cstdlib>
#include<algorithm>
using namespace std; int father[],Q; struct sum
{
int a;
int b;
int c;
}num[]; //路线数 bool cmp(const sum &x,const sum &y) //按长度从小到大快排,
{
return x.c<y.c;//原理有待研究
} int Find(int x) //找出祖先
{
while(x!=father[x])
x=father[x];
return x;
} void Union(int a,int b,int i)
{
if(a!=b)
{
father[a]=b;
Q+=num[i].c; //并入家族且把长度加上来
}
} int main()
{
int T,k,n,m,i,j,l,p,q,c,t;
int ss[];
scanf("%d",&T);
while(T--)
{
scanf("%d%d%d",&n,&m,&k);
for(i=;i<=n;i++)
father[i]=i;
for(i=;i<m;i++)
scanf("%d%d%d",&num[i].a,&num[i].b,&num[i].c);
memset(ss,,sizeof(ss));
for(l=;l<k;l++)
{
scanf("%d",&t);
for(j=;j<t;j++)
scanf("%d",&ss[j]);
for(j=;j<t;j++)
{
if(Find(ss[])!=Find(ss[j]))
father[Find(ss[j])]=Find(ss[]);
}
memset(ss,,sizeof(ss));
}
sort(num,num+m,cmp);//排序
for(i=,Q=;i<m;i++)
{
Union(Find(num[i].a),Find(num[i].b),i);
}
for(i=,t=;t<&&i<=n;i++)
if(father[i]==i)
t++;
if(t==)
printf("-1\n");
else
printf("%d\n",Q);
}
return ;
}
/*
5
6 4 3
1 4 2
2 6 1
2 3 5
3 4 33
2 1 2
2 1 3
3 4 5 6
6 4 3
1 4 3
2 6 2
6 2 1
3 4 33
2 1 2
2 1 3
3 4 5 6
6 4 3
1 4 2
2 6 1
2 3 5
3 4 33
2 1 2
2 2 3
2 4 5
6 4 3
1 4 3
2 6 2
6 2 1
3 4 33
2 1 2
2 1 3
2 4 6*/

在网上找了Kruskal函数,   有待学习!

#include<stdio.h>           //Kruskal函数
#include<algorithm>
using namespace std; typedef struct{
int u;
int v;
int w;
}Edge; const int EdgeNum=;
const int PointNum=; Edge E[EdgeNum];
int P[PointNum]; int union_find(int x) // 并查集
{
return P[x]==x? x : P[x]=union_find(P[x]);
} bool cmp(Edge a,Edge b){ return a.w<b.w; } int MST_Kruskal(int n,int m) // 传入点数和边数
{
int i,j,x,y,k=,sum=;
for(i=;i<n;++i)
{
for(j=;j<n;++j)
{
if(i==j) continue;
if(P[j]==i)
{
k++;
// printf("P[%d]=%d\n",j,i);
}
}
}
// printf("k=%d\n",k);
sort(E,E+m,cmp);
for(i=;k<n&&i<m;++i)
{
x=union_find(E[i].u);
y=union_find(E[i].v);
if(x!=y)
{
sum+=E[i].w;
P[x]=y;
k++;
}
}
if(k<n) return -;
return sum;
} int f[];
int solve(int n,int m,int k)
{
int i,j,t;
for(i=;i<n;++i)
{ // 初始化并查集
P[i]=i;
}
for(i=;i<k;++i){
scanf("%d",&t);
for(j=;j<t;++j)
{
scanf("%d",&f[j]);
f[j]--;
}
for(j=;j<t;++j)
P[union_find(f[j])]=union_find(f[j-]);
}
return MST_Kruskal(n,m);
} int main()
{
int t,n,m,k,i,p,q,c,ans;
scanf("%d",&t);
while(t--)
{
scanf("%d%d%d",&n,&m,&k);
for(i=;i<m;++i)
{
scanf("%d%d%d",&p,&q,&c);
p--;q--;
E[i].u=p;E[i].v=q;E[i].w=c;
}
ans=solve(n,m,k);
printf("%d\n",ans);
}
return ;
}

Connect the Cities(hdu3371)并查集(附测试数据)的更多相关文章

  1. Connect the Cities[HDU3371]

    Connect the Cities Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)T ...

  2. [hdu2874]Connections between cities(LCA+并查集)

    题意:n棵树,求任意两点的最短距离. 解题关键:并查集判断两点是否位于一棵树上,然后求最短距离即可.此题可以直接对全部区间直接进行st表,因为first数组会将连接的两点的区间表示出来. //#pra ...

  3. HDU 3371 Connect the Cities(并查集+Kruskal)

    题目网址:http://acm.hdu.edu.cn/showproblem.php?pid=3371 思路: 这道题很明显是一道最小生成树的题目,有点意思的是,它事先已经让几个点联通了.正是因为它先 ...

  4. PAT 1013 Battle Over Cities(并查集)

    1013. Battle Over Cities (25) 时间限制 400 ms 内存限制 65536 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN, Yue It ...

  5. TOJ 2815 Connect them (kruskal+并查集)

    描述 You have n computers numbered from 1 to n and you want to connect them to make a small local area ...

  6. hdu 2874 Connections between cities (并查集+LCA)

    Connections between cities Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (J ...

  7. 九度OJ 1325:Battle Over Cities(城市间的战争) (并查集)

    时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:376 解决:132 题目描述: It is vitally important to have all the cities connect ...

  8. hdu-2874 Connections between cities(lca+tarjan+并查集)

    题目链接: Connections between cities Time Limit: 10000/5000 MS (Java/Others)     Memory Limit: 32768/327 ...

  9. 1013 Battle Over Cities (25分) DFS | 并查集

    1013 Battle Over Cities (25分)   It is vitally important to have all the cities connected by highways ...

随机推荐

  1. EMACS快捷键

    C = Control M = Meta = Alt | Esc Del = Backspace 基本快捷键(Basic) C-x C-f "find"文件, 即在缓冲区打开/新建 ...

  2. [实战演练]Intel面试题目 - 进栈出栈顺序问题

    电话面试中写C++,逻辑比较清楚的一个题目,一紧张就不能好好地写下来,漏洞百出.以前经常在完善的编译环境中写代码,换了一个白板子上写反而写的不通顺了,犯了一些基础错误,比如stack中的首个元素是to ...

  3. 【CJOJ2616】 【HZOI 2016】偏序 I(cdq分治,树状数组)

    传送门 CJOJ Solution 考虑这是一个四维偏序对吧. 直接cdq套在一起,然后这题有两种实现方法(树状数组的更快!) 代码实现1(cdq+cdq+cdq) /* mail: mleautom ...

  4. Mongodb-- python中使用pymongo连接mongodb数据库

    一.使用 通过pip或者pychrm下载pymongo模块 import json from pymongo import MongoClient from bson import ObjectId ...

  5. docker容器备份、恢复和迁移volume方案

    volume作为数据的载体,在很多情况下需要对其中的数据进行备份.迁移或是恢复.下面一docker容器的volume为例,说一下备份的技巧. 我们先建立一个容器vol_simple,该容器在/date ...

  6. CuratorFramework使用

    CuratorFrameworkFramework是ZooKeeper Client更高的抽象API 自动连接管理: 1. 当ZooKeeper客户端内部出现异常, 将自动进行重连或重试, 该过程对外 ...

  7. MapReducer

    MapReducer    概述        是一个分布式的计算框架(编程模型),最初由由谷歌的工程师开发,基于GFS的分布式计算框架.后来Cutting根据<Google Mapreduce ...

  8. Unity项目接入应用宝SDK实现截图功能

    Unity项目接入应用宝SDK实现截图功能 问题由来 点击应用宝悬浮窗 如图所示 左下角有一个截图按钮 需要解决那些问题 截图信息需要由游戏引擎提供 SDK获取截图信息为同步 但是Unity引擎没有提 ...

  9. POJ 2685

    #include <iostream> #include <string> #define MAXN 26 using namespace std; int _map[MAXN ...

  10. 剑指offer八之跳台阶

    一.题目 一只青蛙一次可以跳上1级台阶,也可以跳上2级.求该青蛙跳上一个n级的台阶总共有多少种跳法. 二.思路 a.如果两种跳法,1阶或者2阶,那么假定第一次跳的是一阶,那么剩下的是n-1个台阶,跳法 ...