zoukankan      html  css  js  c++  java
  • NYOJ--42--dfs水过||并查集+欧拉通路--一笔画问题

    dfs水过:

     1 /*
     2     Name: NYOJ--42--一笔画问题
     3     Author: shen_渊 
     4     Date: 18/04/17 15:22
     5     Description: 这个题用并查集做,更好。在练搜索,试试手 
     6                 本来用的vector存放边,结果,vector并不能当做数组,遍历的时候只能用迭代器
     7                 中间没有数据的部分读取会出错 
     8 输入
     9 第一行只有一个正整数N(N<=10)表示测试数据的组数。
    10 每组测试数据的第一行有两个正整数P,Q(P<=1000,Q<=2000),分别表示这个画中有多少个顶点和多少条连线。
    11 (点的编号从1到P)
    12 随后的Q行,每行有两个正整数A,B(0<A,B<P),表示编号为A和B的两点之间有连线。
    13 输出
    14 如果存在符合条件的连线,则输出"Yes",
    15 如果不存在符合条件的连线,输出"No"。
    16 */
    17 #include<bits/stdc++.h> 
    18 using namespace std;
    19 void dfs(int);
    20 int vis[1005];
    21 int vec[1005][1005];
    22 int outDegree[1005];
    23 int N,P,Q,flag;
    24 int main(){
    25     int N;cin>>N; 
    26     while(N--){
    27         flag = 0;
    28         memset(vec,0,sizeof(vec));
    29         memset(vis,0,sizeof(vis));
    30         memset(outDegree,0,sizeof(outDegree));
    31         cin>>P>>Q;
    32         for(int i=0; i<Q; ++i){
    33             int x,y;cin>>x>>y;
    34             vec[x][y] = vec[y][x] = 1;
    35         }
    36         dfs(1);
    37         int mark = 0;
    38         for(int i=1; i<=P; ++i){
    39             if(outDegree[i] == 0){
    40                 mark = 1;break;
    41             } 
    42             if(outDegree[i]%2)flag++;
    43         }
    44         if(mark)cout<<"No"<<endl;
    45         else if(flag == 0 || flag == 2)cout<<"Yes"<<endl;
    46         else cout<<"No"<<endl;
    47     }
    48     return 0;
    49 }
    50 void dfs(int i){
    51     vis[i] = 1;
    52     for(int k=1; k<=P; ++k){
    53         if(vec[i][k]){
    54             outDegree[i]++;
    55             if(!vis[k])
    56                 dfs(k);
    57         }
    58     }
    59 }

    学到图论了,用并查集+欧拉做一次:

     1  
     2 /*
     3     欧拉路径,无向图
     4     1判断是否为连通图, 
     5     2判断奇点的个数为0或2按照题意,只要是欧拉回路或者通路都符合题意 
     6 */
     7 #include <iostream> 
     8 #include <cstring>
     9 #include <vector>
    10 #include <cstdio>
    11 using namespace std;
    12 int edge[2010];
    13 struct DisjoinSet {
    14     vector<int> father, rank;
    15     
    16     DisjoinSet(int n): father(n), rank(n) {
    17         for (int i=0; i<n; i++) {
    18             father[i] = i;
    19         }
    20     }
    21     
    22     int easy_find(int v)  {//非递归 
    23         int k, j, r;
    24         r = v;
    25         while (r!=father[r]) {
    26             r = father[r];
    27         }
    28         k = v;
    29         while (k!=r) {
    30             j = father[k];
    31             father[k] = r;
    32             k = j;
    33         }
    34         return r;
    35     }
    36     void merge(int x, int y) {
    37         int a = easy_find(x), b = easy_find(y);
    38         if (rank[a] < rank[b]) {
    39             father[a] = b;
    40         } else {
    41             father[b] = a;
    42             if (rank[b] == rank[a]) {
    43                 ++rank[a];
    44             }
    45         }
    46     }
    47 } ; 
    48 
    49 int p, q;
    50 int main()
    51 {
    52 //    freopen("in.txt", "r", stdin);
    53     int N;
    54     scanf("%d", &N);
    55     while (N--) {
    56         memset(edge, 0, sizeof(edge));
    57         scanf("%d %d", &p, &q);
    58         DisjoinSet mfs(2010);
    59         for (int i=0; i<q; i++) {
    60             int a, b;
    61             scanf("%d %d", &a, &b);
    62             edge[a]++;
    63             edge[b]++;
    64             mfs.merge(a, b);
    65         }
    66         int father = mfs.easy_find(1);
    67         int ct = 0;
    68         for (int i=1; i<=p; i++) {
    69             if (mfs.father[i] != father) {
    70                 ct = -1;
    71                 break;
    72             }
    73             if (edge[i] & 1) ct++;
    74         }
    75         if (ct == 0 || ct == 2) printf("Yes
    ");
    76         else printf("No
    ");
    77     }
    78     return 0;
    79 }        
  • 相关阅读:
    hdu1565 用搜索代替枚举找可能状态或者轮廓线解(较优),参考poj2411
    cf1114D 区间dp基础
    poj2411 状态压缩-铺地板题型-轮廓线解法(最优)
    poj3254 炮兵阵地弱化版,记数类dp
    poj2441状态压缩dp基础
    zoj3471 状态压缩dp基础
    北极通讯网络(最小生成树)
    黑暗城堡(生成树)
    关押罪犯(并查集)
    搭配购买(并查集+0/1背包)
  • 原文地址:https://www.cnblogs.com/langyao/p/7251871.html
Copyright © 2011-2022 走看看