POJ3177Redundant Paths(边的双连通性,用vector时一定要去掉重边)

Redundant Paths

Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 9118   Accepted: 3925

Description

In order to get from one of the F (1 <= F <= 5,000) grazing fields (which are numbered 1..F) to another field, Bessie and the rest of the herd are forced to cross near the Tree of Rotten Apples. The cows are now tired of often being forced to take a particular
path and want to build some new paths so that they will always have a choice of at least two separate routes between any pair of fields. They currently have at least one route between each pair of fields and want to have at least two. Of course, they can only
travel on Official Paths when they move from one field to another.

Given a description of the current set of R (F-1 <= R <= 10,000) paths that each connect exactly two different fields, determine the minimum number of new paths (each of which connects exactly two fields) that must be built so that there are at least two separate
routes between any pair of fields. Routes are considered separate if they use none of the same paths, even if they visit the same intermediate field along the way.

There might already be more than one paths between the same pair of fields, and you may also build a new path that connects the same fields as some other path.

Input

Line 1: Two space-separated integers: F and R

Lines 2..R+1: Each line contains two space-separated integers which are the fields at the endpoints of some path.

Output

Line 1: A single integer that is the number of new paths that must be built.

Sample Input

7 7
1 2
2 3
3 4
2 5
4 5
5 6
5 7

Sample Output

2

Hint

Explanation of the sample:

One visualization of the paths is:

   1   2   3
   +---+---+
       |   |
       |   |
 6 +---+---+ 4
      / 5
     /
    /
 7 +

Building new paths from 1 to 6 and from 4 to 7 satisfies the conditions.

   1   2   3
   +---+---+
   :   |   |
   :   |   |
 6 +---+---+ 4
      / 5  :
     /     :
    /      :
 7 + - - - - 

Check some of the routes:

1 – 2: 1 –> 2 and 1 –> 6 –> 5 –> 2

1 – 4: 1 –> 2 –> 3 –> 4 and 1 –> 6 –> 5 –> 4

3 – 7: 3 –> 4 –> 7 and 3 –> 2 –> 5 –> 7

Every pair of fields is, in fact, connected by two routes.

It‘s possible that adding some other path will also solve the problem (like one from 6 to 7). Adding two paths, however, is the minimum.

Source

USACO 2006 January Gold

#include<stdio.h>
#include<string.h>
#include<iostream>
#include<vector>
using namespace std;

vector<int>map[5005];
int low[5005],dfn[5005],stack[5005],sn,deep,k,node[5005],vist[5005];
int MIN(int a,int b){ return a>b?b:a; }
void DFS(int p,int fath)
{
    int u,m;
    stack[++sn]=p; vist[p]=1;
    deep++; low[p]=dfn[p]=deep;
    m=map[p].size();

    for(int j=0;j<m;j++)
    {
        u=map[p][j];
        if(fath==u)continue;
        if(vist[u]==0)
        {
            DFS(u,p);
            low[p]=MIN(low[p],low[u]);
        }
        else if(vist[u]==1)
            low[p]=MIN(low[p],dfn[u]);
    }
    if(low[p]==dfn[p])
    {
        k++;
        while(stack[sn]!=p){
            node[stack[sn]]=k; vist[stack[sn--]]=2;
        }
            node[stack[sn]]=k; vist[stack[sn--]]=2;
    }
}
int answer(int n)
{
    int d[5005]={0},tj;
    sn=deep=k=0;
    DFS(1,-1);
    for(int i=1;i<=n;i++)
    for(int j=0;j<map[i].size();j++)
    {
        tj=map[i][j];
        if(node[i]!=node[tj])
            d[node[i]]++;
    }
    int ans=0;
    for(int i=1;i<=k;i++)
    if(d[i]==1)
    ans++;
    ans++;
    return ans/2;
}
int vv[5005][5005];
int main()
{
    int n,m,a,b;
    while(scanf("%d%d",&n,&m)==2)
    {
        for(int i=1;i<=n;i++)
        {
            map[i].clear(); vist[i]=0;
            for(int j=1;j<=n;j++)
            vv[i][j]=0;
        }
        while(m--)
        {
            scanf("%d%d",&a,&b);
            if(vv[a][b]==0)//去掉重边,以防在计算度时得出错误答案
            {
                map[a].push_back(b);
                map[b].push_back(a);
                vv[a][b]=vv[b][a]=1;
            }
        }
        printf("%d\n",answer(n));
    }
}

POJ3177Redundant Paths(边的双连通性,用vector时一定要去掉重边)

时间: 2025-01-13 15:12:17

POJ3177Redundant Paths(边的双连通性,用vector时一定要去掉重边)的相关文章

poj3177Redundant Paths tarjan缩点

//给一个连通图,问最少须要加入多少条边才干使得 //随意两个点都有两条不同的路走到 //对于一个强连通分量的全部随意两点都能有两点能够到达 //先用tarjan缩点,缩点以后就是一棵树,对于这个树考虑有几个 //叶子节点 ans = (leaf+1)/2 #include<cstdio> #include<cstring> #include<iostream> using namespace std ; const int maxn = 10010 ; int dfn

使用editplus等编程工具时UTF-8编码去掉BOM头方法(转载备查)

Unicode规范中有一个BOM的概念.BOM--Byte Order Mark,就是字节序标记.在这里找到一段关于BOM的说明: 在UCS 编码中有一个叫做"ZERO WIDTH NO-BREAK SPACE"的字符,它的编码是FEFF.而FFFE在UCS中是不存在的字符,所以不应该出现在实际传输中.UCS规范建议我们在传输字节流前,先传输 字符"ZERO WIDTH NO-BREAK SPACE".这样如果接收者收到FEFF,就表明这个字节流是Big-Endia

在预加载新闻时,怎么去掉初始化内容的显示尴尬?

大家好, 作为一名新手码农,最近做了一个屌丝的新闻浏览界面,但是初始化下载新闻的时候,老是会显示我在布局的设置的源信息,最尴尬的是,还是在显示加载对话框的时候就能被看到,强迫症的我,怎么能忍,搞了半天,还是没搞好,求解个位,可以下一下看看,附上源码

CPP-STL:用vector保存对象时保存指针的优点, 以及reserve的使用(转)

代码1 [cpp] view plaincopy #include <vector> #include <stdio.h> class A { public: A() { printf("A()/n"); } ~A() { printf("~A()/n"); } A(const A& other) { printf("other/n"); } }; int main() { A a; A b(a); A c = a

转载:用vector保存对象时保存指针的优点, 以及reserve的使用

#include <vector> #include <stdio.h> class A { public: A() { printf("A()/n"); } ~A() { printf("~A()/n"); } A(const A& other) { printf("other/n"); } }; int main() { A a; A b(a); A c = a; return 0; } 执行结果1 A() o

C++ vector 实现二维数组时, 在类的头文件中定义时遇到&quot;应输入类型符&quot;的问题?

见下,当我在类的声明文件中定义二维vector时,提示我应输入类型说明符; 但是相同的格式定义,在类中将二维vector修改为在源文件中定义就可以顺利通过,并顺利执行打印 打印结果如下: 望大神来解惑!

Poj 3352 Road Construction &amp; Poj 3177 Redundant Paths(边双连通分量+缩点)

Road Construction Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 9465   Accepted: 4699 Description It's almost summer time, and that means that it's almost summer construction time! This year, the good people who are in charge of the ro

STL vector的N种构造方式

1 使用默认无参的构造函数进行构造 vector<int> intVect; 观察内存可以看到生成一个带有0个元素的vector时内存中_Myfirst _Mylast _Myend的值均为0,说明vector对象并没有在堆中分配任何存储空间,仅仅是在栈中分配了16字节存储vecotr对象元素,在这16字节中前4字节如果没猜错,应该是一个虚表指针. Vecotr模版类有三个成员变量 _Myfirst  记录在堆分配数组的首地址 _Mylast  记录在堆中分配数组中最后一个有效数据的下一字节地

STL—Vector简介

有关C++ STL 中的vector向量的用法(代码示例) 一. 简介 Vector是一个称为向量的顺序容器(不明白顺序容器与关联容器的可以Google). 二. 特点 1. 动态(相当于一个动态数组):2. 可用于存放各种数据结构(内置的,自定义的,当然也可以是vector)(当是vector时注意申明格式eg:vector<vector<Information>>与vector< vector<Information> >,前者错误,后者正确,两个‘&g