学习链接:https://blog.csdn.net/chenguolinblog/article/details/7985370?spm=a2c4e.10696291.0.0.2ce319a4sYGZPg
习题链接:https://yq.aliyun.com/articles/252458?spm=a2c4e.11153940.0.0.42a1757bQt463q
How many answers are wrong
HDU 3038
题解&代码:https://www.cnblogs.com/liyinggang/p/5327055.html
#include <stdio.h>
#include <algorithm>
#include <string.h>
using namespace std;
const int N =200010;
int father[N];
int sum[N]; ///记录当前结点到根结点的距离
int _find(int x){
if(x!=father[x]){
int t = father[x];
father[x] = _find(father[x]);
sum[x]+=sum[t];
}
return father[x];
}
int main()
{
int n,m;
while(scanf("%d%d",&n,&m)!=EOF){
for(int i=0;i<=n;i++){
father[i] = i;
sum[i] = 0;
}
int ans = 0;
while(m--){
int a,b,v;
scanf("%d%d%d",&a,&b,&v);
a--;
int roota = _find(a);
int rootb = _find(b);
if(roota==rootb){
if(sum[a]-sum[b]!=v) ans++; ///精华部分1
}
else{
father[roota] = rootb;
sum[roota] = -sum[a]+sum[b]+v; ///精华部分2
}
}
printf("%d\n",ans);
}
return 0;
}
食物链
POJ 1182
代码&题解:https://blog.csdn.net/chenguolinblog/article/details/8019237?spm=a2c4e.10696291.0.0.79a919a4kzULr0
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int MAXN = 50010;
int n , m , ans;
int father[MAXN];
int rank[MAXN];
void init(){
ans = 0;
memset(rank , 0 , sizeof(rank));
for(int i = 1 ; i <= n ; i++)
father[i] = i;
}
int find(int x){
if(x != father[x]){
int fa = father[x];
father[x] = find(father[x]);
rank[x] += rank[fa];
rank[x] %= 3;
}
return father[x];
}
void solve(int mark , int x , int y){
if(x > n || y > n){
ans++;
return;
}
int fx = find(x);
int fy = find(y);
int v = mark == 1 ? 0 : 1;
if(fx != fy){
father[fx] = fy;
rank[fx] = (rank[y]+v-rank[x]+3)%3;
}
else{
if(rank[x] != (rank[y]+v)%3)
ans++;
}
}
int main(){
int mark , x , y;
scanf("%d%d" , &n , &m);
init();
ans = 0;
for(int i = 0 ; i < m ; i++){
scanf("%d%d%d" , &mark , &x , &y);
solve(mark , x , y);
}
printf("%d\n" , ans);
return 0;
}
Find them, Catch them
POJ 1703
题解&代码:https://blog.csdn.net/chenguolinblog/article/details/8016538?spm=a2c4e.10696291.0.0.55e419a43rIuk6
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int MAXN = 1e5+10;
int father[MAXN];
int rank[MAXN];
void init(int n){
memset(rank , 0 , sizeof(rank));
for(int i = 1 ; i <= n ; i++)
father[i] = i;
}
int find(int x){
if(x != father[x]){
int fa = father[x];
father[x] = find(fa);
rank[x] += rank[fa];
rank[x] %= 2;
}
return father[x];
}
void output(int x , int y , int fx , int fy){
if(fx != fy)
puts("Not sure yet.");
else{
if(rank[x] == rank[y])
puts("In the same gang.");
else
puts("In different gangs.");
}
}
int main(){
char ch;
int x , y;
int cas , n , m;
scanf("%d" , &cas);
while(cas--){
scanf("%d%d%*c" , &n , &m);
init(n);
while(m--){
scanf("%c %d %d%*c" , &ch , &x , &y);
int fx = find(x);
int fy = find(y);
if(ch == 'A'){
output(x , y , fx , fy);
}
else{
if(fx != fy){
father[fx] = fy;
rank[fx] = (rank[y]+1-rank[x]+2)%2;
}
}
}
}
return 0;
}
Cube Stacking
POJ 1988
题解&代码:https://blog.csdn.net/chenguolinblog/article/details/8026631?spm=a2c4e.10696291.0.0.255519a4pSwi51
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int MAXN = 300010;
int father[MAXN];
int rank[MAXN];
int max_rank[MAXN];
void init(int n){
memset(rank , 0 , sizeof(rank));
memset(max_rank , 0 , sizeof(max_rank));
for(int i = 1 ; i <= n ; i++)
father[i] = i;
}
int find(int x){
if(father[x] != x){
int fa = father[x];
father[x] = find(fa);
rank[x] += rank[fa];
}
return father[x];
}
void move(int x , int y){
int fx = find(x);
int fy = find(y);
if(fx != fy){
father[fx] = fy;
rank[fx] = max_rank[fy]+1;
max_rank[fy] += max_rank[fx]+1;
}
}
int main(){
char ch;
int n , x , y;
while(scanf("%d%*c" , &n) != EOF){
init(n);
for(int i = 0 ; i < n ; i++){
scanf("%c" , &ch);
if(ch == 'M'){
scanf("%d%d%*c" , &x , &y);
move(x , y);
}
else{
scanf("%d%*c" , &x);
int fx = find(x);// 注意先压缩
printf("%d\n" , rank[x]);
}
}
}
return 0;
}
Supermarket
POJ 1456
贪心+并查集
题解&代码:https://blog.csdn.net/chenguolinblog/article/details/9785381?spm=a2c4e.10696291.0.0.113c19a4siAHbL
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int MAXN = 10010;
struct Node{
int val;
int day;
bool operator<(const Node &s)const{
return val > s.val;
}
};
Node node[MAXN];
int father[MAXN];
int find(int x){
if(father[x] != x)
father[x] = find(father[x]);
return father[x];
}
int solve(int n){
int ans = 0;
for(int i = 1 ; i <= n ; i++){
int fa = find(node[i].day);
if(fa > 0){
father[fa] = fa-1;
ans += node[i].val;
}
}
return ans;
}
int main(){
int n;
while(scanf("%d" , &n) != EOF){
for(int i = 1 ; i < MAXN ; i++)
father[i] = i;
for(int i = 1 ; i <= n ; i++)
scanf("%d%d" , &node[i].val , &node[i].day);
sort(node+1 , node+n+1);
printf("%d\n" , solve(n));
}
return 0;
}
Parity game
POJ 1733
代码&题解:https://blog.csdn.net/chenguolinblog/article/details/9811385?spm=a2c4e.10696291.0.0.6c8d19a4rOQoAN
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int MAXN = 50010;
struct Node{
int x;
int y;
int mark;
};
Node node[MAXN];
int arr[MAXN] , pos;
int father[MAXN] , Rank[MAXN] , num;
void init(){
sort(arr , arr+pos);
num = unique(arr , arr+pos)-arr;
memset(Rank , 0 , sizeof(Rank));
for(int i = 0 ; i <= num ; i++)
father[i] = i;
}
int find(int x){
if(father[x] != x){
int fa = father[x];
father[x] = find(father[x]);
Rank[x] = (Rank[x]+Rank[fa])%2;
}
return father[x];
}
int search(int x){
int left = 0;
int right = num-1;
while(left <= right){
int mid = (left+right)>>1;
if(arr[mid] == x)
return mid;
else if(arr[mid] < x)
left = mid+1;
else
right = mid-1;
}
}
int solve(int n){
for(int i = 0 ; i < n ; i++){
int x = search(node[i].x)+1;
int y = search(node[i].y)+1;
int fx = find(x);
int fy = find(y);
int val = node[i].mark;
if(fx == fy){
if((Rank[x]-Rank[y]+2)%2 != val)
return i;
}
else{
father[fx] = fy;
Rank[fx] = (val+Rank[y]-Rank[x]+2)%2;
}
}
return n;
}
int main(){
int len , n;
char str[10];
while(scanf("%d%d" , &len , &n) != EOF){
pos = 0;
for(int i = 0 ; i < n ; i++){
scanf("%d %d %s" , &node[i].x , &node[i].y , str);
node[i].x--;
arr[pos++] = node[i].x;
arr[pos++] = node[i].y;
if(str[0] == 'e')
node[i].mark = 0;
else
node[i].mark = 1;
}
init();
printf("%d\n" , solve(n));
}
return 0;
}
/*
10
5
1 2 even
3 4 odd
5 6 even
1 6 even
7 10 odd
*/
Rochambeau
POJ 2912
代码&题解:https://blog.csdn.net/chenguolinblog/article/details/9842135?spm=a2c4e.10696291.0.0.7a6519a44ICDgT