POJ-3352 Road Construction

Posted on   Capterlliar  阅读(20)  评论(0编辑  收藏  举报

题意:给出一张无向图,求添加多少条边后任意减去一条边,整张图仍联通。

解:第一个想到的是割边,想对于一条割边,将上下两点连起来,所以输出割边的数量。画了画图觉得不对,对于一条链,把两头连起来就满足要求了,应该求这张图有多少线头,然后把线头数量除以2。然后删掉割边的代码,写着写着发现和上一题相同起来……割点割边碰到了再练吧。

注意这次是无向图,所以不能求出度为0,应该求出度为1.

代码:

复制代码
#include <algorithm>
#include <stack>
#include <vector>
#include <stdio.h>
using namespace std;
#define maxx 10005
#define maxn 10005
#define maxm 50005
#define inf 0x3f3f3f3f
int n,m;
vector<int> e[maxm];
int dfn[maxn]={0},low[maxn]={0};
int cnt=0,vis[maxn]={0};
int colornum=0,color[maxn]={0},num[maxn]={0};
int out[maxn]={0};
stack<int> s;
void paint(int x){
    s.pop();
    vis[x]=0;
    color[x]=colornum;
    num[colornum]++;
}
void tarjan(int now,int fa){
    s.push(now);
    vis[now]=1;
    low[now]=dfn[now]=++cnt;
    for(int i=0;i<e[now].size();i++){
        int to=e[now][i];
        if(to==fa)
            continue;
        if(!dfn[to]){
            tarjan(to,now);
            low[now]=min(low[now],low[to]);
        }
        else if(vis[to])
            low[now]=min(low[now],dfn[to]);
    }
    if(low[now]==dfn[now]){
        colornum++;
        while (s.top()!=now)
            paint(s.top());
        paint(now);
    }
}
signed main() {
    scanf("%d%d",&n,&m);
    for(int i=0;i<m;i++){
        int x,y;
        scanf("%d%d",&x,&y);
        e[x].push_back(y);
        e[y].push_back(x);
    }
    for(int i=1;i<=n;i++)
        if(!dfn[i])
            tarjan(i,0);
    for(int i=1;i<=n;i++){
        for(int j=0;j<e[i].size();j++){
            int to=e[i][j];
            if(color[to]!=color[i])
                out[color[i]]++;
        }
    }
    int ans=0;
    for(int i=1;i<=colornum;i++)
        if(out[i]==1){
            ans++;
        }
    printf("%d\n",(ans+1)/2);
    return 0;
}
View Code
复制代码

 

编辑推荐:
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?
点击右上角即可分享
微信分享提示