• USACO race3


      这个题的第一问的意思是让你求出从0 走到 N必须走的点集的集合, 第二问的意识是判断被一个点分开的两个子图有没有公共边, 对于第一问我们去掉i后如果发现无法从0走向N那么i就是要求得点, 第二问可以用种子填充, 如果发现有一些点被染到了两种颜色那么这个点就是不满足条件的点。代码如下:

    /*
        ID: m1500293
        LANG: C++
        PROG: race3
    */
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <vector>
    
    using namespace std;
    vector<int> G[55];
    int r1[100], nr1;
    int r2[100], nr2;
    
    int vis[100], ed;
    bool dfs(int u, int ii)   //当前在u  不通过ii能否到达终点
    {
        if(u==ed) return true;
        bool res = false;
        vis[u] = true;
        for(int i=0; i<G[u].size(); i++)
        {
            int v = G[u][i];
            if(!vis[v] && v!=ii)
               res = res || dfs(v, ii);
        }
        return res;
    }
    
    
    bool judge(int i)
    {
        memset(vis, 0, sizeof(vis));
        return !dfs(0, i);
    }
    
    bool floodfill(int u, int ii, int col)   //不经过ii点的染色
    {
        if(vis[u] && vis[u]!=col) return false;
        vis[u] = col;
        bool res = true;
        for(int i=0; i<G[u].size(); i++)
        {
            int v = G[u][i];
            if(v!=ii && vis[v]!=col)
                res = res && floodfill(v, ii, col);
        }
        return res;
    }
    
    bool judge1(int i)        //去掉点ii后进行种子填充
    {
        memset(vis, 0, sizeof(vis));
        floodfill(i, -1, 1);
        return floodfill(0, i, 2);
    }
    
    int main()
    {
        freopen("race3.in", "r", stdin);
        freopen("race3.out", "w", stdout);
        int u = 0;
        while(1)
        {
            int t;
            scanf("%d", &t);
            if(t == -1) break;
            while(t!=-2)
            {
                G[u].push_back(t);
                scanf("%d", &t);
            }
            if(t==-2)
            {
                u++;
                continue;
            }
        }
        --u;             //一共0-u个点
        nr1 = 0;
        ed = u;
        for(int i=1; i<u; i++)
        {
            if(judge(i))
                r1[nr1++] = i;
        }
        if(nr1 == 0)
            printf("%d
    ", nr1);
        else
        {
            printf("%d ", nr1);
            for(int i=0; i<nr1; i++)
                printf("%d%c", r1[i], i==nr1-1?'
    ':' ');
        }
        nr2 = 0;
        for(int i=0; i<nr1; i++)
        {
            if(judge1(r1[i]))
                r2[nr2++] = r1[i];
        }
        if(nr2 == 0)
            printf("%d
    ", nr2);
        else
        {
            printf("%d ", nr2);
            for(int i=0; i<nr2; i++)
                printf("%d%c", r2[i], i==nr2-1?'
    ':' ');
        }
        return 0;
    }
  • 相关阅读:
    程序安装打包
    sql 2005 分页存储过程
    带线的无限级下拉树列表
    MapXtreme 2005 学习心得 概述(一)
    存储过程中用到的年,月,周的函数
    委托/事件/线程传参简单理解
    清除svn/vss小工具
    查看数据库连接数
    MapXtreme 2005 学习心得 使用WebTool工具(七)
    C#日期格式化
  • 原文地址:https://www.cnblogs.com/xingxing1024/p/5166801.html
Copyright © 2020-2023  润新知