CF图论一--Students and Shoelaces--拓扑排序+拓扑邻接表常用模板

B. Students and Shoelaces

time limit per test

2 seconds

memory limit per test

256 megabytes

input

standard input

output

standard output

Anna and Maria are in charge of the math club for junior students. When the club gathers together, the students behave badly. They've brought lots of shoe laces to the club and got tied with each other. Specifically, each string ties together two students. Besides, if two students are tied, then the lace connects the first student with the second one as well as the second student with the first one.

To restore order, Anna and Maria do the following. First, for each student Anna finds out what other students he is tied to. If a student is tied to exactly one other student, Anna reprimands him. Then Maria gathers in a single group all the students who have been just reprimanded. She kicks them out from the club. This group of students immediately leaves the club. These students takes with them the laces that used to tie them. Then again for every student Anna finds out how many other students he is tied to and so on. And they do so until Anna can reprimand at least one student.

Determine how many groups of students will be kicked out of the club.

Input

The first line contains two integers n and m — the initial number of students and laces (). The students are numbered from 1 to n, and the laces are numbered from 1 to m. Next m lines each contain two integers a and b — the numbers of students tied by the i-th lace (1 ≤ a, b ≤ n, a ≠ b). It is guaranteed that no two students are tied with more than one lace. No lace ties a student to himself.

Output

Print the single number — the number of groups of students that will be kicked out from the club.

Examples

input

Copy

3 3
1 2
2 3
3 1

output

Copy

0

input

Copy

6 3
1 2
2 3
3 4

output

Copy

2

input

Copy

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

output

Copy

1

Note

In the first sample Anna and Maria won't kick out any group of students — in the initial position every student is tied to two other students and Anna won't be able to reprimand anyone.

In the second sample four students are tied in a chain and two more are running by themselves. First Anna and Maria kick out the two students from both ends of the chain (1 and 4), then — two other students from the chain (2 and 3). At that the students who are running by themselves will stay in the club.

In the third sample Anna and Maria will momentarily kick out all students except for the fourth one and the process stops at that point. The correct answer is one.

问题转化为对每一层进行判断,每一层即一个组,统计有多少层,利用拓扑排序的思想。

#include
using namespace std;
#define maxn 2000+66
#define ll long long
int n,m;
int du[maxn];
int edge[maxn][maxn];
int ans;
int main()
{
    scanf("%d %d",&n,&m);
    for(int i=1; i<=m; i++)
    {
        int a,b;
        scanf("%d %d",&a,&b);
        du[a]++;
        du[b]++;
        edge[a][b]=edge[b][a]=1;
    }
    while(1)
    {
        int flag=0;
        queueq;
        while(q.size())
            q.pop();
        for(int i=1; i<=n; i++)
        {
            if(du[i]==1)
            {
                flag=1;
                q.push(i);
                du[i]=0;
            }
        }
        while(q.size())
        {
            int u=q.front();
            q.pop();
            for(int v=1; v<=n; v++)
            {
                if(edge[u][v])
                {
                    edge[u][v]=edge[v][u]=0;
                    du[v]--;
                }
            }
        }
        if(flag)
            ans++;
        else
            break;
    }
    printf("%d\n",ans);
}

常用邻接表模板

#include
#include
#include
#include
#include
#include
using namespace std;
#define maxn 20000
int num[100000];
int n,m;
struct node
{
    int u;//保存每一条边的起始点
    int v;//保存每一条边的终止点
    int w;//保存每一条边的权值
    int next;//保存每一条边的上一条边的编号
} edge[maxn*2]; //保存每一条边,下标表示每一条边的编号
int head[maxn];//保存每一个顶点的起始边的编号
int k=0;
void add(int u,int v)
{
    edge[k].u=u;
    edge[k].v=v;
    edge[k].next=head[u];
    head[u]=k++;
}
int ans[maxn];
void ToPu()
{
    priority_queue,greater >que;
    while(!que.empty())que.pop();
    for(int i=1; i<=n; i++)
    {
        if(!num[i])
            que.push(i);
    }
    int len=0;
    while(!que.empty())
    {
        int up=que.top();
        que.pop();
        ans[len++]=up;
        for(int k=head[up]; k!=-1; k=edge[k].next)
        {
            int tt=edge[k].v;
            num[tt]--;
            if(!num[tt])
            {
                que.push(tt);
            }
        }
    }
    printf("%d",ans[0]);
    for(int i=1; i

 

你可能感兴趣的:(ACM拓扑排序)