标签:
Time Limit: 8000MS | Memory Limit: 131072K | |
Total Submissions: 3381 | Accepted: 883 | |
Case Time Limit: 3000MS |
Description
Input
Output
Sample Input
3 7 Q 1 2 I 1 2 I 2 3 Q 1 3 D 1 2 Q 1 3 Q 1 1
Sample Output
N Y NY
题意是,给定点数,给出无向边,可以动态的增加删除查询两点是否连通
第一种解法
这里很容易想到图,创建一个邻接表,查询直接用bfs即可,当然dfs也是差不多的,这里给出bfs查询,邻接表,就用vector算了,可以偷偷懒!
#include "stdio.h" #include "string.h" #include "math.h" #include <algorithm> #include <vector> #include <queue> #include <iostream> using namespace std; #define M 1000000 #define N 20005 vector<int> edge[N]; bool vis[N]; queue<int> 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<int>::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<int>::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"); else printf("N\n"); } else if (q == 'I') { inset(s, e); inset(e, s); } else if (q == 'D') { deleteedge(s, e); deleteedge(e, s); } } } return 0; }第二种解法,用并查集加hash表,这里是1000个点,所以可以用hash表,我想要是再大一点就不适用了,用并查集,确实,可以实现,快速查询两点是否连通,但是如果,删除的话,无疑也是要重建并查集,这点,就很费时间了,看源码
#include "stdio.h" #include "string.h" #include "math.h" #include <algorithm> #include <iostream> using namespace std; #define N 1005 #define M 20005 bool 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; else return 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"); else printf("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; }
第三种 方法 邻接表加上并查集,这样比上面两种方法,省了时间,也省了内存#include "stdio.h" #include "string.h" #include "math.h" #include <algorithm> #include <vector> #include <queue> #include <iostream> using namespace std; #define N 1005 #define SCANF scanf vector<int> edge[N]; int ncount; queue<int> que; int father[N]; void initFather(); int insertFather(int s, int e); int findfather(int s); void createFather() { initFather(); int i = 0; vector<int>::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; else return father[s] = findfather(father[s]); } bool query(int s, int e) { if (findfather(s) == findfather(e)) return true; else return false; } void inset(int s, int e) { edge[s].push_back(e); insertFather(s, e); } void deleteedge(int s, int e) { vector<int>::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"); else printf("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; }
标签:
原文地址:http://blog.csdn.net/mengzhengnan/article/details/45834117