fzu2181(点的双连通分量+求奇环)

求出每个点双连通分量,如果在一个点双连通分量中有奇环,则这个分量每个点都在一个奇环中。  关键是要知道怎么求点双连通分量以及点双连通的性质。

fzu2181 http://acm.fzu.edu.cn/problem.php?pid=2181

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
#define N 1100

int n,m,k;
int g[N][N];
int vis[N];
int height[N];
int stk[N];
int deep,top;
int mark[N];
int save[N]; //用来记录特殊状态
int ans;

int dfs(int s,int num)
{
    vis[s]=deep++;
    stk[top++]=s;
    height[s]=num;
    int mi=vis[s];
    for(int i=1;i<=n;i++)
    {
        if(g[s][i]==0) continue;
        if(vis[i]==-1) //这个点未被访问
        {
            dfs(i,num+1);
            if( vis[i]>=vis[s] )//表示这个圈与世无争,必须单独处理掉
            {
                //开始处理!
                int cnt=0;
                int tcnt=0;
                int flag=0;
                while(stk[top-1]!=s)
                {
                    cnt++;
                    if(mark[stk[top-1]]==1) flag=1;//表示这一堆有奇环
                    if(save[stk[top-1]]==1) tcnt++;
                    top--;
                }

                if(flag==1)//这一堆不存在奇环
                {
                    save[s]=1;
                    ans += cnt+1-tcnt;
                }

            }
            else
            {
                mi = min(mi,vis[i]);
            }
        }
        else
        {
            mi=min(mi,vis[i]);//找当前能到达最上方的点
            if( (height[s]-height[i])%2==0 )//表示当前点在一个奇环中
                mark[s]=1;
        }
    }
    vis[s]=mi;
    return vis[s];
}

int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d%d",&n,&m,&k);
        memset(g,0,sizeof(g));
        for(int i=0;i<m;i++)
        {
            int x,y;
            scanf("%d%d",&x,&y);
            g[x][y]=g[y][x]=1;
        }
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
            {
                if(i==j) g[i][j]=0;
                else if(g[i][j]==1) g[i][j]=0;
                else g[i][j]=1;
            }
        //构建逆图
        memset(vis,-1,sizeof(vis));
        memset(save,0,sizeof(save));
        memset(mark,0,sizeof(mark));
        deep=0;
        top=0;
        ans=0;//表示有多少不能参与游戏
        for(int i=1;i<=n;i++)
        {
            if(vis[i]==-1)
            {
                dfs(i,0);
            }
        }
        if(ans<k) printf("What a Pity.\n");
        else printf("Let‘s Fire!\n");
    }
    return 0;
}
时间: 2024-10-08 11:45:36

fzu2181(点的双连通分量+求奇环)的相关文章

hdoj 4738 Caocao&#39;s Bridges【双连通分量求桥】

Caocao's Bridges Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 3000    Accepted Submission(s): 953 Problem Description Caocao was defeated by Zhuge Liang and Zhou Yu in the battle of Chibi. Bu

[cf557d]Vitaly and Cycle(黑白染色求奇环)

题目大意:给出一个 n 点 m 边的图,问最少加多少边使其能够存在奇环,加最少边的情况数有多少种. 解题关键:黑白染色求奇环,利用数量分析求解. 奇环:含有奇数个点的环. 二分图不存在奇环.反之亦成立. #include<cstdio> #include<cstring> #include<algorithm> #include<cstdlib> #include<iostream> #include<cmath> using nam

zoj 2588 Burning Bridges【双连通分量求桥输出桥的编号】

Burning Bridges Time Limit: 5 Seconds      Memory Limit: 32768 KB Ferry Kingdom is a nice little country located on N islands that are connected by M bridges. All bridges are very beautiful and are loved by everyone in the kingdom. Of course, the sys

hdoj 4612 Warm up【双连通分量求桥&amp;&amp;缩点建新图求树的直径】

Warm up Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others)Total Submission(s): 5093    Accepted Submission(s): 1131 Problem Description N planets are connected by M bidirectional channels that allow instant transport

poj 1144 Network【双连通分量求割点总数】

Network Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 11042   Accepted: 5100 Description A Telephone Line Company (TLC) is establishing a new telephone cable network. They are connecting several places numbered by integers from 1 to N

POJ2942 Knights of the Round Table 点双连通分量,逆图,奇圈

题目链接: poj2942 题意: 有n个人,能够开多场圆桌会议 这n个人中,有m对人有仇视的关系,相互仇视的两人坐在相邻的位置 且每场圆桌会议的人数仅仅能为奇书 问有多少人不能參加 解题思路: 首先构图,将全部的仇视关系视为一条边,最后再取已经得到的图的逆图, 这样图上连接的边就代表能够相邻而坐的关系 然后就是找奇圈了,首先就是要找图中的环(点双连通分量) 这个环为奇环的条件:不是二分图||这个环中的部分点属于其它奇环 这个推断能够通过将已找到的环进行dfs黑白染色推断 最后不在奇环内的总和即

UVALive - 3523 Knights of the Round Table(无向图的双连通分量)

题目大意:有n个骑士经常举行圆桌会议,每次圆桌会议至少要有3个骑士参加(且每次参加的骑士数量是奇数个),且所有互相憎恨的骑士不能坐在圆桌旁的相邻位置,问有多少个骑士不可能参加任何一个会议 解题思路:以骑士为点建立无向图G.如果两个骑士可以相邻(即他们并不互相憎恨),即可连一条边. 则题目就转化为求不在任何一个简单奇圈上的结点个数 首先,圈就是一个双连通的分量,所以第一件事就是将所有的双连通分量求出来,接着再判定这个双连通分量是不是奇圈 奇圈的判定就是用二分图染色判定,如果某个圈能被二分图染色,那

LA 3523 双连通分量+二分图判定

3523 - Knights of the Round Table Time limit: 4.500 seconds Being a knight is a very attractive career: searching for the Holy Grail, saving damsels in distress, and drinking with the other knights are fun things to do. Therefore, it is not very surp

POJ 2942 Knights of the Round Table 黑白着色+点双连通分量

题目来源:POJ 2942 Knights of the Round Table 题意:统计多个个骑士不能參加随意一场会议 每场会议必须至少三个人 排成一个圈 而且相邻的人不能有矛盾 题目给出若干个条件表示2个人直接有矛盾 思路:求补图  能够坐在一起 就是能够相邻的人建一条边 然后假设在一个奇圈上的都是满足的 那些不再不论什么一个奇圈的就是不满足 求出全部奇圈上的点 总数减去它就是答案 首先有2个定理 1.一个点双连通分量是二分图 你就没有奇圈 假设有奇圈  那就不是二分图  充分必要条件 所