zoukankan      html  css  js  c++  java
  • 欧拉回路

    .下面是判有没有欧拉路或欧拉回路的,用并查集来做,判断是否联通,注意欧拉回路包括欧拉路。

    无向图:回路:所有点度都是偶数,路:起点终点是奇数

    有向图:回路:所有点的入度等于出度,路:起点或终点,一个点入度比出度大一,一个点出度比入度大一。

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    
    using namespace std;
    const int maxm = 1e3 + 5;
    int indeg[maxm], pa[maxm], ran[maxm], isin[maxm];
    
    void make_set(int x){
    pa[x] = x;
    ran[x] = 0;
    }
    
    int findx(int x)
    {
        int r = x, temp;
        while(pa[r] != r) r = pa[r];
        while(x != r)
        {
            temp = pa[x];
            pa[x] = r;
            x = temp;
        }
        return x;
    }
    void unio(int x, int y) {
    x = findx(x);
    y = findx(y);
    if(x == y)return ;
    if(ran[x] > ran[y]) {
    pa[y] = x;
    }
    else {
    pa[x] = y;
    if(ran[x] == ran[y]) {
    ran[y]++;
    }
    }
    }
    int n, m, x, y;
    int main() {
    while(~scanf("%d", &n)) {
        if(n == 0) break;
        scanf("%d", &m);
        memset(indeg, 0, sizeof(indeg));
    //    memset(outdeg, 0, sizeof(outdeg));
        memset(isin, 0, sizeof(isin));
        for(int i = 1; i <= n; i++) {
            make_set(i);
        }
        for(int i = 1; i <= m; i++) {
            scanf("%d%d", &x, &y);
            unio(x, y);
            indeg[x]++;
            indeg[y]++;
            isin[x] = isin[y] = 1;
        }
        int num = 0;
        for(int i = 1; i <= n; i++) {
            if(isin[i] && findx(i) == i)
            num++;
        }
        if(num > 1) {
            printf("0
    ");
            continue;
        }
        int flag = 0;
        for(int i = 1; i <= n; i++) {
            if(isin[i] && indeg[i] % 2) {
                flag = 1;
            }
        }
        if(flag) printf("0
    ");
        else printf("1
    ");
    }
    
    
    return 0;
    }
    //这种类型是看存不存在欧拉回路或者道路,大部分是并查集的知识。

     题目:john's trip

    https://vjudge.net/contest/280900#problem/G

     Johnny 有了一台新车,他想去访问他所有的朋友(赤裸裸的炫耀?),他的朋友有很多,住在城市中的街道上,于是他就开始规划自己的路了,在这个城市中有很多街道,他想找一个路径,这个路径经过一个街道仅一次,但能访问完他所有的朋友,他从他父母家出发,并且回来时也必须在他父母家。

      在这个城市中,一共有N(N < 1995)个街道,共有M(M <= 44)个转折点,转折点就是一个街道的两端,每条街道和转折点的编号都不同。如果在一个转折点有多种选择,他会优先选择街道编号比较小的。

      让你帮忙写一个程序,找到这个路径,如果找不到就打印“Round trip does not exist.”,从 1 号转折点出发,最后必须回到 1 号转折点,经过每条街道仅一次,访问完他所有的朋友,街道是双向的,但是不能掉头。

    //这个题目edge存的是出发点与道路的长度,用vis数组标记是否存过,按字典序的话因为本来就是0-len,所以就是字典序排的
    //注意这个dfs是到底才开始回溯,所以是反的

    #include<cstdio> #include<algorithm> #include<cstring> using namespace std; typedef pair<int, int> pii; const int maxm = 2000; int deg[50], isin[50], edge[50][maxm]; int road[maxm], len, vis[maxm]; int now; //void make_set(int x){ // pa[x] = x; //} //int findx(int x) { //if (x != pa[x]) { //pa[x] = findx(pa[x]); //} //return pa[x]; //} // //void unio(int x, int y) { //x = findx(x); //y = findx(y); //if(x == y)return ; //pa[x] = y; //} void dfs(int x) { int i; for(i = 1; i <= len;i++) {
    //i是指街道的编号。
    if(edge[x][i] && !vis[i]){ // printf("%d ", i); vis[i] = 1; dfs(edge[x][i]); road[++now] = i; } // printf("%d ", i); } } int x, y, t, home; int main() { while(~scanf("%d%d", &x, &y)) { if(x == 0 && y == 0) break; len = -1; home = min(x, y); // for(int i = 1; i < maxm; i++) { // make_set(i); // } memset(deg, 0, sizeof(deg)); memset(isin, 0, sizeof(isin)); memset(edge, 0, sizeof(edge)); memset(vis, 0, sizeof(vis)); while(x != 0 && y != 0) { scanf("%d", &t); len = max(len, t); deg[x]++; deg[y]++; isin[x] = isin[y] = 1; // edge[x][t] += y; // edge[y][t] += x; edge[x][t] = y; edge[y][t] = x; scanf("%d%d", &x, &y); } int flag = 0; for(int i = 1; i <= 48; i++) { if(isin[i] && deg[i] % 2) { flag = 1; break; } } if(flag) { printf("Round trip does not exist. "); continue; } now = 0; dfs(home); // sort(road + 1, road + now + 1); for(int i = now; i > 0; i--) { if(i == now) printf("%d", road[i]); else printf(" %d", road[i]); } printf(" "); } return 0; }

    https://vjudge.net/contest/280900#problem/P

    The necklace

    这个题目和上面那个差不多。


    #include<cstdio> #include<algorithm> #include<cstring> using namespace std; typedef pair<int, int> pii; const int maxm = 55; int pa[maxm], deg[maxm], isin[maxm], edge[maxm][maxm]; pii road[1005]; int now; void make_set(int x){ pa[x] = x; } int findx(int x) { if (x != pa[x]) { pa[x] = findx(pa[x]); } return pa[x]; } void unio(int x, int y) { x = findx(x); y = findx(y); if(x == y)return ; pa[x] = y; } void dfs(int x) { int i; for(i = 1; i <= 50;i++) { if(edge[x][i]){ // printf("%d ", i); edge[x][i]--; edge[i][x]--; dfs(i); road[now++] = make_pair(x, i);
    //这个题目是要打印每条路的两个端点。 }
    // printf("%d ", i); } } int t, n, x, y; int main() { scanf("%d", &t); int index = 0; while(t--) { scanf("%d", &n); int home; for(int i = 1; i <= 50; i++) { make_set(i); } memset(deg, 0, sizeof(deg)); memset(isin, 0, sizeof(isin)); memset(edge, 0, sizeof(edge)); while(n--) { scanf("%d%d", &x, &y); unio(x, y); home = x; deg[x]++; deg[y]++; edge[x][y]++; edge[y][x]++; isin[x] = isin[y] = 1; } int ant = 0; // printf("%d ", ant); for(int i = 1; i <= 50; i++) { if(isin[i] && findx(i) == i) { ant++; } } if(ant > 1) { printf("Case #%d ", ++index); printf("some beads may be lost "); continue; } int flag = 0; for(int i = 1; i <= 50; i++) { if(isin[i] && deg[i] % 2 != 0) { flag = 1; break; } } if(flag) { printf("Case #%d ", ++index); printf("some beads may be lost "); } else { now = 1; dfs(home); printf("Case #%d ", ++index); for(int i = now - 1; i > 0; i--) { printf("%d %d ", road[i].first, road[i].second); } printf(" "); } } return 0; }
  • 相关阅读:
    macbook 无声音解决方案
    webapck dev server代理请求 json截断问题
    百度卫星地图开启
    服务器 nginx配置 防止其他域名绑定自己的服务器
    记一次nginx php配置的心路历程
    遇到npm报错read ECONNRESET怎么办
    运行svn tortoiseSvn cleanup 命令失败的解决办法
    svn add 命令 递归目录下所有文件
    m4出现Please port gnulib freadahead.c to your platform! Look at the definition of fflush, fread, ungetc on your system, then report this to bug-gnulib."
    Ubuntu下安装GCC,mpc、mpfr、gmp
  • 原文地址:https://www.cnblogs.com/downrainsun/p/10323342.html
Copyright © 2011-2022 走看看