蓝桥杯6.15训练
今日总结:
裤子给的sort模板:
https://paste.ubuntu.com/p/sJHGVctC7C/
- 并查集
- hdu1232
#include<cstdio>
#include<iostream>
using namespace std;
const int maxn = 1006;
int pre[maxn];
int num = maxn;
int N,M;
void init(){
for(int i = 1;i <= N;i ++){
pre[i] = i;
}
num = N-1;
return ;
}
int find(int x){
if(x == pre[x]){
return pre[x];
}
pre[x] = find(pre[x]);
return pre[x];
}
void uniont(int start,int end){
int x = find(start);
int y = find(end);
if(x != y){
pre[x] = y;
num --;
}
}
int main(){
while(scanf("%d",&N)){
if (N == 0){
break;
}
scanf("%d",&M);
init();
for(int i = 0;i < M;i ++){
int start,end;
scanf("%d %d",&start,&end);
uniont(start,end);
}
printf("%d\n",num);
}
}
- 题目:hdu 5326
#include <cstdio>
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
const int maxn = 105;
int n,k;
int a,b;
int pre[maxn];
int cnt[maxn];
int ans;
void init(){
for(int i = 1;i <= n;i ++){
pre[i] = i;
}
memset(cnt,0,sizeof(cnt));
ans = 0;
}
void creat(){
pre[b] = a;
}
void find(int x){
int r = x;
while(r != pre[r]){
r = pre[r];
cnt[r] ++;
}
}
void getans(){
for(int i = 1;i <= n;i ++){
if(cnt[i] == k){
ans ++;
}
}
}
int main(){
int times = 1;
while((scanf("%d%d",&n,&k) != EOF)){
init();
for(int i = 0;i < n-1;i ++){
scanf("%d %d",&a,&b);
creat();
}
for(int i = 1;i <=n;i ++){
find(i);
}
getans();
printf("%d\n",ans);
}
return 0;
}
- hdu 2545
超时代码:
#include<cstdio>
#include<iostream>
#include <bits/stdc++.h>
using namespace std;
const int maxn = 100005;
int n,m;
int a,b;
int pre[maxn];
int x,y;
void init(){
for(int i = 1;i <= n;i ++){
pre[i] = i;
}
}
void creat(){
pre[b] = a;
}
void search(int x,int y){
int flag = 0;
//先确认一次y是否为x的祖先:
int r = x;
while(r != pre[r]){
r = pre[r];
if(r == y){
printf("pfz\n");
return;
}
}
r = y;
while(r != pre[r]){
r = pre[r];
if(r == x){
printf("lxh\n");
return;
}
}
//开始前进
while(flag == 0){
x = pre[x];
r = y;
while(r != pre[r]){
r = pre[r];
if(r == x){
flag = 1;
printf("lxh\n");
return;
}
}
y = pre[y];
int r = x;
while(r != pre[r]){
r = pre[r];
if(r == y){
flag = 1;
printf("pfz\n");
return;
}
}
}
return ;
}
int main(){
while(scanf("%d %d",&n,&m)){
if((n == m)&&(n == 0)){
break;
}
init();
for(int i = 1;i <= n-1;i ++){
scanf("%d %d",&a,&b);
creat();
}
for(int i = 1;i <= m;i ++){//接下来的n次询问,查找谁会赢
scanf("%d %d",&x,&y);
search(x,y);
}
}
return 0;
}
可执行代码:
#include<cstdio>
#include<iostream>
#include <bits/stdc++.h>
using namespace std;
const int maxn = 100005;
int n,m;
int a,b;
int pre[maxn];
int x,y;
int cnt1,cnt2;//分别统计其与根节点的距离
void init(){
for(int i = 1;i <= n;i ++){
pre[i] = i;
}
cnt1 = 0;
cnt2 = 0;
}
void creat(){
pre[b] = a;
}
int find(int x){
int r = x;
int cnt = 0;
while(r != pre[r]){
cnt ++;
r = pre[r];
}
return cnt;
}
void search(int x,int y){
cnt1 = find(x);
cnt2 = find(y);
if(cnt1 > cnt2){
printf("pfz\n");
}
else printf("lxh\n");
return ;
}
int main(){
while(scanf("%d %d",&n,&m)){
if((n == m)&&(n == 0)){
break;
}
init();
for(int i = 1;i <= n-1;i ++){
scanf("%d %d",&a,&b);
creat();
}
for(int i = 1;i <= m;i ++){//接下来的n次询问,查找谁会赢
scanf("%d %d",&x,&y);
search(x,y);
}
}
return 0;
}
- hdu 1213
WA代码:
#include <cstdio>
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1005;
int pre[maxn];
int n,m;
int a,b;
int cnt;
void init(){
for(int i = 1;i <= n ;i ++){
pre[i] = i;
}
cnt = 0;
}
void creat(){
pre[b] = a;
}
void uniont(){
for(int i = 1;i <= n;i ++){//路径压缩
int r = i;
while(r != pre[r]){
pre[r] = pre[pre[r]];
r = pre[r];
}
}
for(int i = 0;i <= n;i ++){
if(i == pre[i]){
cnt ++;
}
}
cnt --;
}
int main(){
int t;
scanf("%d",&t);
while(t-- ){
scanf("%d %d",&n,&m);
init();
for(int i = 1;i <= m;i ++){
scanf("%d %d",&a,&b);
creat();
}
uniont();
printf("%d",cnt);
}
}
AC代码:
#include <cstdio>
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1005;
int pre[maxn];
int n,m;
int a,b;
int cnt;
void init(){
for(int i = 1;i <= n ;i ++){
pre[i] = i;
}
cnt = 0;
}
int find(int x){
if(x != pre[x]){
pre[x] = find(pre[x]);
}
return pre[x];
}
void creat(){
int x,y;
x = find(a);
y = find(b);
if(x != y){
pre[y] = x;
}
}
void uniont(){
for(int i = 1;i <= n;i ++){
if(find(i) == i){
cnt ++;
}
}
}
int main(){
int t;
scanf("%d",&t);
while(t-- ){
scanf("%d %d",&n,&m);
init();
for(int i = 1;i <= m;i ++){
scanf("%d %d",&a,&b);
creat();
}
uniont();
printf("%d\n",cnt);
}
return 0;
}
- hdu 1856
#include <cstdio>
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
const int maxn = 100005;
int pre[maxn];
int a,b;
int stu[maxn];
int n;
void init(){
for(int i = 1;i < maxn;i ++){
pre[i] = i;
}
memset(stu,0,sizeof(stu));
}
int find(int x){
if(pre[x] != x){
pre[x] = find(pre[x]);
}
return pre[x];
}
void uniont(){
int x =find(a);
int y = find(b);
if(x != y){
pre[y] = x;
}
}
int count(){
int ans = 0;
int k = 0;
for(int i = 1;i < maxn;i ++){
stu[find(i)]++;
}
for(int i = 1;i < maxn;i ++){
if(find(i) == i){
ans = (stu[i] > ans)?stu[i]:ans;
}
}
return ans;
}
int main(){
while(scanf("%d",&n)!= EOF){
init();
for(int i = 1;i <= n;i ++){
scanf("%d %d",&a,&b);
uniont();
}
int ans = 0;
ans = count();
printf("%d\n",ans);
}
}
- hdu 3938
tle代码:
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <bits/stdc++.h>
using namespace std;
const int maxn = 50005;
int t;
int a,b,c;
int n,m,q;
int k1 = 0;
int city[maxn];
int k = 0;
int start = 0;
typedef struct{
int pre;
int v;
}Pr;
Pr pre[maxn];
typedef struct {
int a;
int b;//前一个连着的节点
int v;//权值
}Edge;
typedef struct {
int order;
int req;
int ans;
}Request;
Request re[maxn];
Edge edge[maxn];
bool cmp1(const Request &re1,const Request &re2){
return re1.req < re2.req;
}
bool cmp2(const Request &re1,const Request &re2){
return re1.order < re2.order;
}
bool cmp3(const Edge &e1,const Edge &e2){
return e1.v < e2.v;
}
void init(){
for(int i = 1;i <= n;i ++){
edge[i].a = 0;
edge[i].b = 0;
edge[i].v = 0;
re[i].order = i;
re[i].req = 0;
re[i].ans = 0;
pre[i].pre = i;
pre[i].v = maxn;
}
k1 = 0;
start = 1;
}
int find(int x){
if(x != pre[x].pre){
pre[x].pre = find(pre[x].pre);
}
return pre[x].pre;
}
void uniont(){
int i = 0;
for(i = start; i <= m;i ++){
if((edge[i].v <= k)&&(edge[i].v > k1)){//表示这两个城市可达
int x = find(edge[i].a);
int y = find(edge[i].b);
if(x != y){
pre[x].pre = y;
pre[y].v = edge[i].v;
}
}
else if(edge[i].v > k){
break;
}
}
start = i;
}
int count(){
int ans = 0;
for(int i = 1;i <= n;i ++){
city[find(i)]++;
}
for(int i =1;i <= n;i ++){
if((i == find(i))&&(pre[i].v <= k )){
ans += city[i]*(city[i] -1)/2;
}
}
return ans;
}
int main(){
int ans;
while(scanf("%d %d %d",&n,&m,&q)!= EOF){
init();
//读入所有边
for(int i = 1;i <= m;i ++){
scanf("%d %d %d",&a,&b,&c);
edge[i].a = a;
edge[i].b = b;
edge[i].v = c;
}
sort(edge+1,edge+m+1,cmp3);
//读入所有请求
for(int i = 1;i <= q;i ++){
scanf("%d",&re[i].req);
}
//对所有的请求进行排序
sort(re+1,re+q+1,cmp1);
//debug
//开始用并查集建图
for(int i = 1;i <= q;i ++){
k = 0;
ans = 0;
memset(city,0,sizeof(city));
k = re[i].req;
if(i >= 2){
k1 = re[i-1].req;
}
uniont();
ans = count();
re[i].ans = ans;
}
sort(re+1,re+q+1,cmp2);
//将结果输出
for(int i = 1;i <= q;i ++){
printf("%d\n",re[i].ans);
}
}
return 0;
}
AC代码:
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <bits/stdc++.h>
using namespace std;
const int maxn = 50005;
int t;
int a,b,c;
int n,m,q;
// int k1 = 0;
int city[maxn];
// int k = 0;
typedef struct{
int pre;
int v;
int num;
}Pr;
Pr pre[maxn];
typedef struct {
int a;
int b;//前一个连着的节点
int v;//权值
}Edge;
typedef struct {
int order;
int req;
int ans;
}Request;
Request re[maxn];
Edge edge[maxn];
bool cmp1(const Request &re1,const Request &re2){
return re1.req < re2.req;
}
bool cmp2(const Request &re1,const Request &re2){
return re1.order < re2.order;
}
bool cmp3(const Edge &e1,const Edge &e2){
return e1.v < e2.v;
}
void init(){
for(int i = 1;i <= n;i ++){
pre[i].pre = i;
pre[i].v = maxn;
pre[i].num = 1;
}
// k1 = 0;
}
int find(int x){
if(x != pre[x].pre){
pre[x].pre = find(pre[x].pre);
}
return pre[x].pre;
}
int uniont(int k,int &i){
int ans = 0;
for(; i <= m; i ++) {
if(edge[i].v > k) break;
int x = find(edge[i].a);
int y = find(edge[i].b);
if(x != y){
pre[x].pre = y;
pre[y].v = edge[i].v;
ans += pre[x].num * pre[y].num;
pre[y].num += pre[x].num;
pre[x].num = 0;
}
}
return ans;
}
// int count(){
// int ans = 0;
// for(int i = 1;i <= n;i ++){
// city[find(i)]++;
// }
// for(int i =1;i <= n;i ++){
// if((i == find(i))&&(pre[i].v <= k )){
// ans += city[i]*(city[i] -1)/2;
// }
// }
// return ans;
// }
int main(){
int ans;
while(scanf("%d %d %d",&n,&m,&q)!= EOF){
init();
//读入所有边
for(int i = 1;i <= m;i ++){
scanf("%d %d %d",&a,&b,&c);
edge[i].a = a;
edge[i].b = b;
edge[i].v = c;
}
sort(edge+1,edge+m+1,cmp3);
//读入所有请求
for(int i = 1;i <= q;i ++){
scanf("%d",&re[i].req);
re[i].order = i;
re[i].ans = 0;
}
//对所有的请求进行排序
sort(re+1,re+q+1,cmp1);
//debug
//开始用并查集建图
int eid = 1;
for(int i = 1;i <= q;i ++){
// ans = 0;
// memset(city,0,sizeof(city));
// k = re[i].req;
if(i >= 2){
// k1 = re[i-1].req;
re[i].ans = re[i-1].ans;
}
// ans = count();
re[i].ans += uniont(re[i].req,eid);
}
sort(re+1,re+q+1,cmp2);
//将结果输出
for(int i = 1;i <= q;i ++){
printf("%d\n",re[i].ans);
}
}
return 0;
}