CSU1580: Outing(图论+DP)

来源:互联网 发布:约瑟夫环算法 编辑:程序博客网 时间:2024/05/19 09:11

Description

Input

Output

Sample Input

4 41 2 3 4

Sample Output

4

HINT

Source

NCPC 2014


题意:有n个人,车上有k个座位

然后n个输入,a[i],代表i坐车的先决条件是a[i]必须坐车


思路:这道题是用的图论的方法,图论是我队友主攻,我主要是提供了一些思路

首先,对于成环的情况,这换里面的人都是可以上车的

那么我们把环看成一个点,那么就能形成几条链,那么这些人都是可以上车的

其次,我们要考虑座位的数量,因为有环的话,对于这条链,必然是以环开头,环不满足的话,整条链都不能满足,例如环满足需要四个座位,但是车上只有三个座位,那么这整条链是不满足的


下面的代码是队友的,有爱的同学自己慢慢理解吧。。。


#include<stdio.h>#include<vector>#include<string.h>using namespace std;const int N = 1005; int dfn[N],low[N],Stack[N],flag[N],vist[N],num[N],top,deep,tn;vector<int>mapt1[N],mapt2[N]; void init(int n){    for(int i=1;i<=n;i++)    {        mapt1[i].clear();        mapt2[i].clear();        dfn[i]=0;        num[i]=0;        vist[i]=0;    }    tn=top=deep=0;}int tt;void dfs(int u){    deep++; vist[u]=tt;    dfn[u]=low[u]=deep;    Stack[++top]=u;    int len=mapt1[u].size();    for(int i=0;i<len;i++)    {        int v=mapt1[u][i];         if(vist[v]==0)        {            dfs(v);            if(low[u]>low[v])                low[u]=low[v];        }        else if(vist[v]==tt&&low[u]>dfn[v])            low[u]=dfn[v];    }    if(low[u]==dfn[u])    {        tn++;        while(u!=Stack[top])        {            flag[Stack[top]]=tn; num[tn]++;top--;         }        flag[Stack[top]]=tn; num[tn]++; top--;     }}int in[N],have[N][N];void rebuilMap(int n){    tt=0;    for(int i=1;i<=n;i++)        if(vist[i]==0)        {            tt++;            dfs(i);        }     memset(in,0,sizeof(in));    memset(have,0,sizeof(have));     for(int i=1;i<=n;i++)    {        int u=flag[i];        for(int j=0;j<mapt1[i].size();j++)        {            int v=flag[mapt1[i][j]];            if(u==v||have[v][u])                continue;            in[u]++; have[v][u]=1;            mapt2[v].push_back(u);        }    }}int k;int solve(){    int dp[N],a[N],m=0;    memset(dp,0,sizeof(dp));    dp[0]=1;    for(int i=1;i<=tn;i++)    if(in[i]==0&&num[i]<=k)    {        a[m++]=i;        for(int j=k;j>=num[i];j--)        if(dp[j-num[i]]==1)            dp[j]=1;    }    while(m--)    {        int u=a[m];        for(int i=0;i<mapt2[u].size();i++)        {            int v=mapt2[u][i];            in[v]--;            if(in[v]==0&&num[v]<=k)            {                a[m++]=v;                for(int j=k;j>=num[v];j--)                if(dp[j-num[v]]==1)                    dp[j]=1;            }        }    }    for(int i=k;i>=0;i--)        if(dp[i])        return i;    return 0;}int main(){    int n;    scanf("%d%d",&n,&k);    {        init(n);        for(int i=1;i<=n;i++)        {            int j;            scanf("%d",&j);            mapt1[i].push_back(j);        }        rebuilMap(n);        printf("%d\n",solve());    }    return 0;}


0 0
原创粉丝点击