维护图的联通性

4    维护图的连通性

      Source file:        graph.cpp/pas
      Input file:         graph.in
      Output file:        graph.out
      Time limit:        1s

4.1    Description

     给定一个无向图,写一个程序处理以下两种操作:

   1.  删去一条边  

   2.  询问两点,  是否连通

4.2    Input

     输入文件的第一行包含三个整数,, ,依次代表图的顶点数、边数、
询问的个数。
     接下来   行,每行两个整数 , ,描述图中的一条边  。接下来
  行,每行三个整数 ,, ,描述一个操作。若      则操作代表删去边
 ,否则操作代表询问点  和   是否连通。数据保证删除的边一定存
在。

4.3    Output

     对于每个询问操作输出一行字符串 “Yes”  (连通)或者“No”  (不连
通)。

4.4    Example(s)

      Input    Output
      3  2  4  Yes
      1  2     No
      2  3     Yes
      2  1  2
      1  1  2
      2  1  3
      2  2  3

4.5    Specification

     对于所有的数据,n<=1000,   m<=100000 ,   q<=100000,   可能存在
重边。

这是一个并查集的问题,你不可能不知道吧!

附代码如下:

#include    <vector>
#include    <string>
#include    <bitset>
#include   <cstring>
#include   <cstdlib>
#include  <iostream>
#include <algorithm>
using namespace std;

#ifndef unix
    #define lld "%I64d"
    #define llu "%I64u"
#else
    #define lld "%lld"
    #define llu "%llu"
#endif

#define FOR(a,b,c)  for(int (a)=b;(a)<=(c);++(a))
#define FORD(a,b,c) for(int (a)=b;(a)>=(c);--(a))
#define FORV(a,t,b) for(vector<t>::iterator a=b.begin();a!=b.end();++a)
#define MAX(a,b)                   a=max(a,b)
#define MIN(a,b)                   a=min(a,b)
#define BLA                      printf("\n")
#define pb                          push_back
#define mp                          make_pair
#define gc                            getchar
#define RT                             return
#define BB                             second
#define AA                              first
#define bk                              break
#define LINF             0x3f3f3f3f3f3f3f3fll
#define INF                        0x3f3f3f3f
#define eps                              1e-8
#define DINF                             1e20

//#define Generator

typedef long long           ll;
typedef unsigned            ui;
typedef unsigned long long ull;
typedef pair<int,int>      pii;
typedef pair<ll ,ll >      pll;

const int MAXN= 200008;
const int MOD = 1000000007;

template <class T> inline void CLR(T &g)             {T t;swap(t,g);}
template <class T> inline void CLR(T &g,int a){memset(g,a,sizeof g);}
template <class T> inline void CPY(T &a,T &b) {memcpy(a,b,sizeof a);}
template <class T> inline bool inr(T a,T b,T c)  {RT (a>=b && a<=c);}
inline int acc(int a,int b)                    {RT !!(a & (1<<b-1));}
inline int fil(int a,int b,int c)    {RT a & ~(1<<b-1) | (1<<b-1)*c;}

int N,M,K,Q;

int fa[MAXN];
int an(int x){
	if (fa[x]==x) RT x;
	RT fa[x]=an(fa[x]);
}
int co(int a, int b){
	a=an(a), b=an(b);
	if (a!=b) fa[a]=b;
}

struct Q{
	int u, v, t, ans;
}q[MAXN];

int g[1006][1006];

int main(){
	#ifndef Generator
	#ifndef ONLINE_JUDGE
		freopen("graph.in" ,"r",stdin );
		freopen("graph.out","w",stdout);
	#endif
	#endif
	#ifdef Generator
		freopen("input.txt","w",stdout);
		srand((ui)time(NULL));
	#endif
	int T,o=0;
	scanf("%d%d%d", &N, &M, &Q);
	FOR(i, 1, M){
		int a, b;
		scanf("%d%d", &a, &b);
		if (a>b) swap(a, b);
		g[a][b]++;
	}
	FOR(i, 1, Q){
		scanf("%d%d%d", &q[i].t, &q[i].u, &q[i].v);
		if (q[i].u>q[i].v)
			swap(q[i].u, q[i].v);
		if (q[i].t==1)
			g[q[i].u][q[i].v]--;
	}

	FOR(i, 1, N) fa[i]=i;
	FOR(i, 1, N)
		FOR(j, i+1, N)
			if (g[i][j]) co(i, j);

	FORD(i, Q, 1)
		if (q[i].t!=1)
			q[i].ans = (an(q[i].u)==an(q[i].v));
		else
			co(q[i].u, q[i].v);
	FOR(i, 1, Q)
		if (q[i].t!=1)
			if (q[i].ans) printf("Yes\n");
			else printf("No\n");
	RT 0;
}


如此便可

你可能感兴趣的:(算法)