第一次爆零
作者:互联网
前言:打代码慢没关系,除非你不用心
一开始打了好多,但由于孙姓同学(gavensun.com)运行了一个恶意程序,然后本篇博文并没有保存,所以前言就说这么多
第一题,注意数据范围,不要吊儿郎当
第二,三题(并查集求联通块:不要乱写,撞对垃圾样例并不一定对
2
道路
1000ms/128MB
M市有 n个城镇,同时有 m条道路(无向),城镇之间可以通过一条或多条道路到达。为了全面建设小
康社会,现要新建设一些道路,使得所有城镇之间两两可以互相到达。
请你计算出最少还需要建设多少条道路
输入格式:
第一行:两个正整数,分别是城镇数目 n(n<1000)和道路数目 m(m <= n * (n – 1)/2));随后的
m行对应 m条道路,每行给出两个正整数,分别是道路相连的两个城镇编号。城镇从 1到 N编号。
两个城市间可以有多条道路相通。
输出格式:一行一个整数。为最少需要建设的道路。
1 #include<cstdio> 2 #include<algorithm> 3 #define DEEEEEEEE 4 using namespace std; 5 const int MAXN = 1000+9; 6 const int MAXM = 500000+9; 7 8 int n,m,ans; 9 int fa[MAXN]; 10 bool visit[MAXN]; 11 12 int father(int x) { 13 if(x == fa[x]) return x; 14 return fa[x] = father(fa[x]); 15 } 16 17 int main() { 18 #ifdef DEEEEEEEE 19 freopen("b.in","r",stdin); 20 freopen("b.out","w",stdout); 21 #endif 22 scanf("%d%d",&n,&m); 23 for(int i = 1; i <= n; i++) fa[i] = i; 24 int fx,fy; 25 for(int i = 1, x, y; i <= m; i++) { 26 scanf("%d %d",&x,&y); 27 fx = father(x), fy = father(y); 28 fa[fx] =fy;//把道路的代表元素联通 29 } 30 for(int i = 1; i <= n; i++) { // 求联通块个数 31 if(!visit[father(i)]) {//先写father(i) 这才把fa[i]算出来 32 visit[fa[i]] = 1; 33 ans++; 34 } 35 } 36 printf("%d",ans-1);//ans个联通块,最少需要连ans-1条道路 37 return 0; 38 }
3.
现在一个平面上画了 n 个矩形。每一个矩形的两边都与坐标轴相平行,且矩形定点的坐标均为整数。现定
义满足如下性质的图形为一个块:
1. 每一个矩形都是一个块;
2. 如果两个块有一段公共的部分,那么这两个块就会形成一个新的块,否则这两个块就是不同的。
示例:
图 1矩形形成了两个不同的块。图 2矩形形成了一个块。找不同块的个数
#include<cstdio> #include<algorithm> #define DEEEEEEEE using namespace std; const int MAXN = 7000+9; int n,ans; int fa[MAXN]; bool visit[MAXN]; int father(int x) { if(x == fa[x]) return x; return fa[x] = father(fa[x]); } struct node{ int x1,y1,x2,y2; }e[MAXN]; bool judge(int x1,int y1, int x2, int y2, int x111, int y111, int x222, int y222) { //找关系的时候冷静一点,不要慌 if(x2<x111 || x1>x222 || y1>y222 || y2<y111 ) return 0;//没有一点相交 if( (x1==x222 || x2==x111) && (y1==y222 || y2==y111) ) return 0;//相交一点 return 1; } int main() { #ifdef DEEEEEEEE freopen("c.in","r",stdin); freopen("c.out","w",stdout); #endif scanf("%d",&n); for(int i = 1; i <= n; i++) fa[i] = i; int x1,y1,x2,y2,x111,y111,x222,y222; // 矩形1号 矩形2号 int f1,f2; for(int i = 1; i <= n; i++) { scanf("%d%d%d%d",&x1,&y1,&x2,&y2); e[i].x1 = x1, e[i].x2 = x2, e[i].y1 = y1, e[i].y2 = y2; for(int j = 1; j < i; j++) { x111 = e[j].x1 , y111 = e[j].y1 , x222 = e[j].x2 , y222 = e[j].y2 ; if(judge(x1,y1,x2,y2,x111,y111,x222,y222) ) { f1 = father(i), f2 = father(j); fa[f1] = f2; } } } for(int i = 1; i <= n; i++) { if(!visit[father(i)]) { visit[fa[i]] = 1; ans++; } } printf("%d",ans); return 0; }
第四题:分层图(仔细分析题目,不要看见那么多的条件就害怕
消失的 c题(c.cpp/c.in/c.out)
1000ms/128MB
题目描述
N 个虫洞,M 条单向跃迁路径。从一个虫洞沿跃迁路径到另一个虫洞需要消耗一定量的燃料和 1 单
位时间。虫洞有白洞和黑洞之分。设一条跃迁路径两端的 虫洞质量差为 delta。
1.从白洞跃迁到黑洞,消耗的燃料值减少 delta,若该条路径消耗的燃料值变为负数的话,取为 0。
2.从黑洞跃迁到白洞,消耗的燃料值增加 delta。
3.路径两端均为黑洞或白洞,消耗的燃料值不变化。
每过 1 单位时间黑洞变为白洞,白洞变为黑洞。
在飞行过程中,可以选择在一个虫洞停留 1 个单位时间,如果当前为白洞,则不消耗燃料,否则消
耗 s[i]的燃料。现在请你求出从 虫洞 1 到 N 最少的燃料消耗,保证一定存在 1 到 N 的路线。
输入格式第 1 行:2 个正整数 N,M
第 2 行:N 个整数,第 i 个为 0 表示虫洞 i 开始时为白洞,1 表示黑洞。
第 3 行:N 个整数,第 i 个数表示虫洞 i 的质量 w[i]。
第 4 行:N 个整数,第 i 个数表示在虫洞 i 停留消耗的燃料 s[i]。第 5..第 M+4 行:每行 3 个整数,u,v,k,表示在没有影响的情况下,从虫洞 u到虫洞 v 需要消耗燃料 k。
输出格式
一个整数,表示最少的燃料消耗。
样例输入
4 5
1 0 1 0
10 10 100 10
5 20 15 10
1 2 30
2 3 40
1 3 20
1 4 200
3 4 200
样例输出
130
数据范围
对于 30%的数据: 1<=N<=100,1<=M<=500
对于 60%的数据: 1<=N<=1000,1<=M<=5000
对于 100%的数据: 1<=N<=5000,1<=M<=30000
其中 20%的数据为 1<=N<=3000 的链
1<=u,v<=N, 1<=k,w[i],s[i]<=200
样例说明
按照 1->3->4 的路线。
标签:爆零,int,白洞,消耗,第一次,fa,燃料,MAXN 来源: https://www.cnblogs.com/virtualtan/p/10809328.html