ACM: 图论题 poj 3177 同 3352

来源:互联网 发布:win7如何安装linux系统 编辑:程序博客网 时间:2024/05/20 01:09
RedundantPaths

 

Description

In order to get from one of theF (1 <= F <= 5,000) grazing fields(which are numbered 1..F) to another field, Bessie and the rest ofthe herd are forced to cross near the Tree of Rotten Apples. Thecows are now tired of often being forced to take a particular pathand want to build some new paths so that they will always have achoice of at least two separate routes between any pair of fields.They currently have at least one route between each pair of fieldsand want to have at least two. Of course, they can only travel onOfficial 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 twodifferent fields, determine the minimum number of new paths (eachof which connects exactly two fields) that must be built so thatthere 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 offields, and you may also build a new path that connects the samefields as some other path.

Input

Line 1: Two space-separatedintegers: F and R

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

Output

Line 1: A single integer that isthe 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

 

题意: 略

 

解题思路:

     1. 思路同poj 3352, 不过有万恶的重边, 需要判重.

 

代码:

#include <cstdio>
#include <iostream>
#include <cstring>
using namespace std;
#define MAX 10005
#define MAXSIZE 5005

struct node
{
 int u, v;
 int next;
}edges[MAX*3];

int n, m;
int first[MAX], num;
int stack[MAXSIZE], top, low[MAXSIZE], dfn[MAXSIZE], count;
int degree[MAXSIZE], bcc[MAXSIZE];
bool vis[MAXSIZE], g[MAXSIZE][MAXSIZE];

inline int min(int a, int b)
{
 return a < b ? a : b;
}

inline void add(int u, int v)
{
 edges[num].u = u;
 edges[num].v = v;
 edges[num].next = first[u];
 first[u] = num++;
 g[u][v] = true;
}

void readGraph()
{
 top = num = count = 0;
 memset(first, -1, sizeof(first));
 memset(stack, 0, sizeof(stack));
 memset(low, 0, sizeof(low));
 memset(dfn, 0, sizeof(dfn));
 memset(degree, 0, sizeof(degree));
 memset(vis, false, sizeof(vis));
 memset(bcc, 0, sizeof(bcc));
 memset(g, false, sizeof(g));
 int u, v;
 for(int i = 0; i < m; ++i)
 {
  scanf("%d %d",&u, &v);
  if( g[u][v] ) continue;
  add(u, v);
  add(v, u);
 }
}

void tarjan(int u, int fa, int deep)
{
 dfn[u] = low[u] = deep;
 vis[u] = true;
 stack[top++] = u;
 for(int e = first[u]; e != -1; e =edges[e].next)
 {
  int v = edges[e].v;
  if(v != fa)
  {
   if( !low[v])
   {
    tarjan(v,u, deep+1);
    low[u]= min(low[u], low[v]);
   }
   else if(vis[v] )
    low[u]= min(low[u], dfn[v]);
  }
 }

 if(low[u] == dfn[u])
 {
  count++;
  int v;
  do
  {
   v =stack[--top];
   vis[v] =false;
   bcc[v] =count;
  }while( v != u );
 }
}

int solve()
{
 int i, result = 0;
 for(i = 1; i <= n; ++i)
 {
  if( !low[i] )
   tarjan(i, 0,1);
 }

 int u, v;
 for(i = 0; i < num; i += 2)
 {
  u = edges[i].u;
  v = edges[i].v;
  if( bcc[u] != bcc[v] )
  {
   degree[bcc[u] ]++;
   degree[bcc[v] ]++;
  }
 }

 for(i = 1; i <= count;++i)
 {
  if( degree[i] == 1)
   result++;
 }
 return (result+1)/2;
}

int main()
{
// freopen("input.txt", "r", stdin);
 while(scanf("%d %d", &n,&m) != EOF)
 {
  readGraph();
  int result = solve();
  printf("%d\n", result);
 }
 return 0;
}

0 0
原创粉丝点击