码迷,mamicode.com
首页 > 其他好文 > 详细

vijos1325 桐桐的糖果计划

时间:2017-06-18 23:44:38      阅读:379      评论:0      收藏:0      [点我收藏+]

标签:根据   void   oid   哪些   stack   names   space   道路   题意   

Description

桐桐是一个快乐的小朋友,他生活中有许多许多好玩的事,让我们一起来看看吧……

桐桐很喜欢吃棒棒糖。他家处在一大堆糖果店的附近。

但是,他们家的区域经常出现塞车、塞人等情况,这导致他不得不等到塞的车或人走光了他才能去买到他最爱吃的棒棒糖品种。于是,他去找市长帮他修路,使得每两个糖果店之间至少有两条完全不同的路。可是市长经费有限,于是让桐桐找出哪些路被塞住后会使某些糖果店与糖果店间无法到达及最少的修路条数。你能帮助他吃到他最喜爱的糖果吗?

注:1->3->2  和 1->3->4->2 为不完全不同的路,即不符合题意的路。

1->3->4->2 和 1->5->2 为完全不同的路,即符合题意的路。

Input

输入第一行是两个数n,m(n<=5000,m<=10000)

接下来的m行,每行两个数i,j,表示i,j间有一条边连接。

Output

输出有两行。第一行为塞住后就不可以到达某些糖果店的道路条数,第二行为最少的修路条数。

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

上图是样例所表示的一个图。 下图是改变后的图,其中虚线表示应连接的边。

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

Sample Input

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

Sample Output

3
2
 
 
 
今天突然想复习一下tarjan
这题写的很明白,就是找环的个数,根据题目描述,判断环就行了
我写的很麻烦,dalao们写的比我好多了..
#include<cstdio>
#include<iostream>
#include<vector>
#include<stack>
#include<cstring>
using namespace std;
int head[5010],num[5010],low[5010],vis[5010],cstack[5010],belong[5010],in[5010],step=0,count=0;
struct map
{
    int a;
    int b;
};
map map1[20200];
stack<int>mstack;
void make(int i,int x,int y)
{
    map1[i].a=y;
    map1[i].b=head[x];
    head[x]=i;
}
bool choose(int x,int y)
{
    if((x&1)!=0&&y==x+1)
    return true;
    if((x&1)==0&&y==x-1)
    return true;
    return false;
}
void tarjan(int v,int e)
{
    int i,j,l,u;
    step++;
    num[v]=step;
    low[v]=step;
    vis[v]=1;
    cstack[v]=1;
    mstack.push(v);
    for(i=head[v];i;i=map1[i].b)
    {
        if(choose(i,e)==1)
        continue;
        l=map1[i].a;
        if(vis[l]==0)
        {
            tarjan(l,i);
            low[v]=min(low[v],low[l]);
        }
        else
        if(cstack[l])
        low[v]=min(low[v],num[l]);
    }
    if(low[v]==num[v])
    {
        count++;
        do
        {
            u=mstack.top();
            mstack.pop();
            belong[u]=count;
            cstack[u]=0;
        }while(u!=v);
    }
}
int main()
{
    int n,m,x,y,count1=0;
    int i,j;
    scanf("%d%d",&n,&m);
    for(i=1;i<=m;i++)
    {
        scanf("%d%d",&x,&y);
        make(i*2-1,x,y);
        make(i*2,y,x);
    }
    for(i=1;i<=n;i++)
    if(vis[i]==0)
    tarjan(i,-1);
    printf("%d\n",count-1);
    for(i=1;i<=n;i++)
    for(j=head[i];j;j=map1[j].b)
    if(belong[i]!=belong[map1[j].a])
    in[belong[i]]++;
    for(i=1;i<=count;i++)
    if(in[i]==1)
    count1++;
    if((count1-1)/2+1==1)
    cout<<"0";
    else
    printf("%d",(count1-1)/2+1);
}

vijos1325 桐桐的糖果计划

标签:根据   void   oid   哪些   stack   names   space   道路   题意   

原文地址:http://www.cnblogs.com/ashon37w/p/7045752.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!