#include<bits/stdc++.h>
using namespace std;
const int maxn = 50010;
int n, k, ans;
int f[3*maxn];
inline void getInit(){
int nn = 3*n;
for(int i = 1; i <= nn; i++)
f[i] = i;
}
inline int find(intx){
if(f[x] == x) returnx;
return f[x] = find(f[x]);
}
inline void merge(intx, inty){
f[find(x)] = find(y);
}
inline bool ask(intx, inty){
if(find(x) == find(y)) return1;
return0;
}
int main(){
scanf("%d%d", &n, &k);
getInit();
for(int i = 1, op, x, y; i <= k; i++){
scanf("%d%d%d", &op, &x, &y);
if(x > n || y > n){
ans++;
continue;
}
if(op == 1){
if(ask(x, y+n) || ask(x, y+2*n) || ask(y, x+n) || ask(y, x+2*n)){
ans++;
continue;
}
merge(x, y), merge(x+n, y+n), merge(x+2*n, y+2*n);
}
elseif(op == 2){
if(x == y || ask(x, y) || ask(x, y+2*n)){
ans++;
continue;
}
merge(x, y+n);
merge(x+n, y+2*n);
merge(x+2*n, y);
}
}
printf("%d\n", ans);
return0;
}
Eg3.关押罪犯
大概是食物链的降级版。如果要表示多种关系一定要开多倍空间!初始化多倍!
#include<cstdio>#include<algorithm>#include<iostream>usingnamespacestd;
int n, m;
int f[100010];
struct node{
int x, y, w;
} edge[100010];
inlineint read(){
int num = 0;
char c;
bool flag = false;
while((c = getchar()) == ' ' || c == '\n' || c == '\r');
if(c == '-') flag = true;
else num = c - '0';
while(isdigit(c = getchar())) num = num*10 + c - '0';
return (flag? -1 : 1)*num;
}
bool cmp(node a, node b){
return a.w > b.w;
}
int find(int x){
if(f[x] == x) return x;
return f[x] = find(f[x]);
}
int main(){
//freopen("love.in", "r", stdin);//freopen("love.out", "w", stdout);scanf("%d%d", &n, &m);
for(int i = 1; i <= m; i++)
scanf("%d%d%d", &edge[i].x, &edge[i].y, &edge[i].w);
sort(edge+1, edge+m+1, cmp);
int nn = 2*n;
for(int i = 1; i <= nn; i++) f[i] = i;
for(int i = 1; i <= m; i++){
int fx = find(edge[i].x);
int fy = find(edge[i].y);
int ex = find(edge[i].x+n);
int ey = find(edge[i].y+n);
if(fx == fy){
printf("%d", edge[i].w);
return0;
}
f[fx] = ey;
f[fy] = ex;
}
printf("0\n");
return0;
}
#include<iostream>#include<algorithm>#include<cstdio>usingnamespacestd;
struct road
{
int begin,end,crow;
}a[20000];
int n,m,s,t,fa[20000],ans;
int fin(int x)
{
if (fa[x]==x)
return x;
fa[x]=fin(fa[x]);
return fa[x];
}
bool cmp(road a,road b)
{
return a.crow<b.crow;
}
int main()
{
scanf("%d %d %d %d",&n,&m,&s,&t);
int i;
for (i=1;i<=n;i++)
fa[i]=i;
for (i=1;i<=m;i++)
scanf("%d %d %d",&a[i].begin,&a[i].end,&a[i].crow);
sort(a+1,a+m+1,cmp);
for (i=1;i<=m;i++)
{
int fx=fin(a[i].begin),fy=fin(a[i].end);
if (fx!=fy)
fa[fx]=fy;
if (fin(s)==fin(t))
{ans=a[i].crow;break;}
}
cout<<ans;
}
**Eg2.无线通讯网**
贪心,只需要统计最小生成树上较小的边,较大的用卫星电话即可
#include<bits/stdc++.h>usingnamespacestd;
constint maxn = 550;
int s, p, tot, cnt, f[maxn];
struct data{
double x, y;
} a[550];
struct node{
int x, y;
double w;
} edge[maxn*maxn];
inlinebool cmp(node p, node q){
return p.w < q.w;
}
int find(int now){
if(now == f[now]) return now;
return f[now] = find(f[now]);
}
inlinevoid Kruskal(){
for(int i = 1; i <= p; i++) f[i] = i;
for(int i = 1; i <= cnt; i++){
int fx = find(edge[i].x);
int fy = find(edge[i].y);
if(fx != fy){
f[fx] = fy;
tot++;
if(tot == p - s){
printf("%.2lf\n", edge[i].w);
return;
}
}
}
}
inlinedouble getnum(double p, double q){
returnsqrt(p*p + q*q);
}
int main(){
scanf("%d%d", &s, &p);
for(int i = 1; i <= p; i++){
scanf("%lf%lf", &a[i].x, &a[i].y);
//printf("%.2lf %.2lf", a[i].x, a[i].y);
}
for(int i = 1; i <= p; i++)
for(int j = i+1; j <= p; j++)
cnt++, edge[cnt].x = i, edge[cnt].y = j, edge[cnt].w = getnum(a[i].x - a[j].x, a[i].y - a[j].y);
sort(edge+1, edge+cnt+1, cmp);
/*for(int i = 1; i <= cnt; i++)
printf("%d %d %.2lf ", edge[i].x, edge[i].y, edge[i].w);*/
Kruskal();
return0;
}