• poj 3177 边连通分量


    思路:

    dfs求出所有点的low值,然后对每个连通分量进行缩点,可以通过low来进行缩点。虽然在同一连通分量里可能存在不同的low值,但这并不影响缩点。将每个连通分量缩为一个点后,只要求出这个缩点后的树上的叶子节点个数就行了。结果为(leaf+1)/2。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    #include<map>
    #define Maxn 1010
    #define Maxm Maxn*10
    using namespace std;
    int index[Maxn],degree[Maxn],dfn[Maxn],low[Maxn],e,n,lab=0,num,visit[Maxn][Maxn];
    void init()
    {
        memset(index,-1,sizeof(index));
        memset(degree,0,sizeof(degree));
        memset(low,0,sizeof(low));
        memset(dfn,0,sizeof(dfn));
        memset(visit,0,sizeof(visit));
        e=lab=num=0;
    }
    struct Edge{
        int from,to,next,v;
    }edge[Maxm];
    void addedge(int from, int to)
    {
        edge[e].v=0;
        edge[e].from=from;
        edge[e].to=to;
        edge[e].next=index[from];
        index[from]=e++;
        edge[e].v=0;
        edge[e].to=from;
        edge[e].from=to;
        edge[e].next=index[to];
        index[to]=e++;
    }
    int dfs(int u)
    {
        dfn[u]=low[u]=++lab;
        int i,j,temp;
        for(i=index[u];i!=-1;i=edge[i].next)
        {
            temp=edge[i].to;
            if(edge[i].v) continue;
            edge[i].v=edge[i^1].v=1;
            if(!dfn[temp])
            {
                dfs(temp);
                low[u]=min(low[u],low[temp]);
            }
            low[u]=min(low[u],dfn[temp]);
        }
        return 0;
    }
    int solve()
    {
        int i,j,temp;
        for(i=1;i<=n;i++)
        {
            for(j=index[i];j!=-1;j=edge[j].next)
            {
                int temp=edge[j].to;
                if(low[i]!=low[temp])
                {
                    degree[low[i]]++;
                }
            }
        }
        return 0;
    }
    int main()
    {
        int m,i,j,a,b;
        while(scanf("%d%d",&n,&m)!=EOF)
        {
            init();
            for(i=1;i<=m;i++)
            {
                scanf("%d%d",&a,&b);
                if(!visit[a][b])
                {
                    addedge(a,b);
                    visit[a][b]=visit[b][a]=1;
                }
            }
            int ans=0;
            dfs(1);
            solve();
            for(i=1;i<=n;i++)
                if(degree[i]==1)
                    ans++;
            printf("%d
    ",(ans+1)/2);
        }
        return 0;
    }
  • 相关阅读:
    zlib压缩一个文件为gzip格式
    最短路径算法Dijkstra
    用MonoDevelop开发Linux游戏
    Flask入门1HelloWorld
    Windows+Linux打造和谐的开发环境
    WinCE 6.0下的编译选项
    使用cvrtbin.exe转换bin文件到nb0
    美的电磁炉(SK2106)加热断断续续问题的快速修复(原创)
    解决XP下双网卡不能同时用
    USB驱动程序打包(转)
  • 原文地址:https://www.cnblogs.com/wangfang20/p/3202031.html
Copyright © 2020-2023  润新知