Poj2838 Graph Connectivity

Source: Internet
Author: User

Poj2838 Graph Connectivity
Graph Connectivity

Time Limit:8000 MS   Memory Limit:131072 K
Total Submissions:3381   Accepted:883
Case Time Limit:3000 MS

Description

Let us consider UndirectedGraph G = <V, E>. at first there is no edge in the graph. you are to write a program to calculate the connectivity of two different vertices. your program shocould maintain the functions inserting or deleting an edge.

Input

The first line of the input contains an integer numbers N (2 <=n <= 1000) -- the number of vertices in G. the second line contains the number of commands Q (1 <= Q <= 20000 ). then the following Q lines describe each command, and there are three kinds of commands:

I u v: Insert an edge (u, v). And we guarantee that there is no edge between nodes u and v, when you face this command.
D u v: Delete an existed edge (u, v). And we guarantee that there is an edge between nodes u and v, when you face this command.
Q u v: A querying command to ask the connectivity between nodes u and v.

You shoshould notice that the nodes are numbered from 1 to N.

Output

Output one line for each querying command. Print "Y" if two vertices are connected or print "N" otherwise.

Sample Input

3 7Q 1 2I 1 2I 2 3Q 1 3D 1 2Q 1 3Q 1 1

Sample Output

NYN

Y

The question is: given the number of points, giving an undirected edge, you can dynamically Add a delete query to check whether two points are connected.

Solution 1

It is easy to think of graphs here. Create an adjacent table and directly use bfs for queries. Of course, dfs is similar. Here we provide bfs queries and the adjacent table, so we can use vector for calculation. We can be very lazy!

 

#include "stdio.h"#include "string.h"#include "math.h"#include #include 
 
  #include 
  
   #include 
   
    using namespace std;#define M 1000000#define N 20005vector
    
      edge[N];bool vis[N];queue
     
       que;bool query(int s, int e){if (s == e)return true;memset(vis, false, sizeof(vis));vis[s] = true;while (!que.empty()){que.pop();}que.push(s);while (!que.empty()){int k = que.front();que.pop();vector
      
       ::iterator it;for (it = edge[k].begin(); it != edge[k].end(); it++){if (*it == e)return true;if (!vis[*it]){que.push(*it);vis[*it] = true;}}}return false;}void inset(int s, int e){edge[s].push_back(e);}void deleteedge(int s, int e){vector
       
        ::iterator it;int i;for (it = edge[s].begin(), i = 0; it != edge[s].end(); it++, i++){if (*it == e){edge[s].erase(it);return;}}}void init(){for (int i = 0; i < N; i++){edge[i].clear();}}int main(){int n, tcase;char q;int s, e;while (scanf("%d", &tcase) != EOF){init();scanf("%d", &n);while (n--){getchar();q = getchar();scanf("%d%d", &s, &e);//printf("%c %d %d", q, s, e);if (q == 'Q'){if (query(s, e))printf("Y\n");elseprintf("N\n");}else if (q == 'I'){inset(s, e);inset(e, s);}else if (q == 'D'){deleteedge(s, e);deleteedge(e, s);}}}return 0;}
       
      
     
    
   
  
 
The second solution is to use and check the set and add the hash table. Here there are 1000 points, so we can use the hash table. I don't want to apply it if it is a little bigger. Use and query the set. Indeed, yes, fast Query

 

Whether the two points are connected, but if they are deleted, they will undoubtedly re-build and query the set. This is very time-consuming. Check the source code.

 

#include "stdio.h"#include "string.h"#include "math.h"#include #include 
 
  using namespace std;#define N 1005#define M 20005bool edge[N][N];int father[N];void initFather();int insertFather(int s, int e);int findfather(int s);int ncount;struct node {int s, e;};node queue[M];int sum = 0;void createFather(){initFather();for (int i = 0; i < sum;i++){if (edge[queue[i].s][queue[i].e])insertFather(queue[i].s, queue[i].e);}}void initFather(){for (int i = 0; i <= ncount; i++){father[i] = i;}}int insertFather(int s, int e){int x = findfather(s);int y = findfather(e);if ( x != y)father[x] = findfather(y);return 0;}int findfather(int s){if (father[s] == s)return s;elsereturn father[s] = findfather(father[s]);}bool query(int s, int e){if (findfather(s) == findfather(e))return true;else return false;}void deleteedge(int s, int e){edge[s][e] = false;}void init(){memset(edge, false, sizeof(edge));sum = 0;createFather();}int main(){int n,tcase;char q;int s, e;while (scanf_s("%d", &tcase) != EOF){//while (tcase--){ncount = tcase;init();scanf_s("%d", &n);while (n--){getchar();q = getchar();scanf_s("%d%d", &s, &e);//printf("%c %d %d", q, s, e);if (q == 'Q'){if (query(s, e))printf("Y\n");elseprintf("N\n");}else if (q == 'I'){edge[s][e] = true;edge[e][s] = true;queue[sum].s = s;queue[sum].e = e;sum++;insertFather(s, e);}else if (q == 'D'){deleteedge(s, e);deleteedge(e, s);createFather();}}}}return 0;}
 

The third method adds and queries the set in the adjacent table, which saves time and memory compared with the preceding two methods.

 

 

#include "stdio.h"#include "string.h"#include "math.h"#include #include 
 
  #include 
  
   #include 
   
    using namespace std;#define N 1005#define SCANF scanfvector
    
      edge[N];int ncount;queue
     
       que;int father[N];void initFather();int insertFather(int s, int e);int findfather(int s);void createFather(){initFather();int i = 0;vector
      
       ::iterator it;for (int s = 0; s <= ncount; s++){for (it = edge[s].begin(), i = 0; it != edge[s].end(); it++, i++){insertFather(s, *it);}}}void initFather(){for (int i = 0; i <= ncount; i++){father[i] = i;}}int insertFather(int s, int e){int x = findfather(s);int y = findfather(e);if (x != y)father[x] = findfather(y);return 0;}int findfather(int s){if (father[s] == s)return s;elsereturn father[s] = findfather(father[s]);}bool query(int s, int e){if (findfather(s) == findfather(e))return true;elsereturn false;}void inset(int s, int e){edge[s].push_back(e);insertFather(s, e);}void deleteedge(int s, int e){vector
       
        ::iterator it;int i;for (it = edge[s].begin(), i = 0; it != edge[s].end(); it++, i++){if (*it == e){edge[s].erase(it);return;}}}void init(){for (int i = 0; i <= ncount; i++){edge[i].clear();}createFather();}int main(){int n, tcase;char q;int s, e;while (SCANF("%d", &tcase) != EOF){ncount = tcase;init();SCANF("%d", &n);while (n--){getchar();q = getchar();SCANF("%d%d", &s, &e);//printf("%c %d %d", q, s, e);if (q == 'Q'){if (query(s, e))printf("Y\n");elseprintf("N\n");}else if (q == 'I'){inset(s, e);inset(e, s);}else if (q == 'D'){deleteedge(s, e);deleteedge(e, s);createFather();}}}return 0;}
       
      
     
    
   
  
 

 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.