Outing

Outing

题目描述

Organising a group trip for the elderly can be a daunting task... Not least because of the fussy participants, each of whom will only make the trip on condition that some other participant also comes. 
After some effort, you have taken from each of your participants a number, indicating that this participant will refuse to join the excursion unless the participant with that number also joins– the less choosy simply give their own number. This would be easy enough to resolve (just send all of them) but the bus you are going to use during the trip has only a ?xed number of places.
Given the preferences of all participants, ?nd the maximum number of participants that can join.

输入

The ?rst line of input contains two integers n and k (1 ≤ k ≤ n ≤ 1 000), where n denotes the total number of participants and k denotes the number of places on the bus.
The second line contains n integers x i for i = 1, 2, . . . , n, where 1 ≤ x i ≤ n. The meaning of x i is that the i-th participant will refuse to join the excursion unless the x i -th participant also joins.

输出

Output one integer: the maximum number of participants that can join the excursion, so that all the participants’ preferences are obeyed and the capacity of the bus is not exceeded.

样例输入

4 4
1 2 3 4

样例输出

4分析:先求下强连通分量,然后图就变成了树,团或树指向团;   然后对于树或团直接01背包,对于树指向团的可取min——max,背包可用差分优化;代码:
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <climits>
#include <cstring>
#include <string>
#include <set>
#include <map>
#include <unordered_map>
#include <queue>
#include <stack>
#include <ctime>
#include <vector>
#include <list>
#define rep(i,m,n) for(i=m;i<=n;i++)
#define rsp(it,s) for(set<int>::iterator it=s.begin();it!=s.end();it++)
#define mod 1000000007
#define inf 0x3f3f3f3f
#define vi vector<int>
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define ll long long
#define pi acos(-1.0)
#define pii pair<int,int>
#define Lson L, mid, ls[rt]
#define Rson mid+1, R, rs[rt]
#define sys system("pause")
#define freopen freopen("in.txt","r",stdin)
const int maxn=1e3+10;
using namespace std;
ll gcd(ll p,ll q){return q==0?p:gcd(q,p%q);}
ll qpow(ll p,ll q){ll f=1;while(q){if(q&1)f=f*p;p=p*p;q>>=1;}return f;}
inline ll read()
{
    ll x=0;int f=1;char ch=getchar();
    while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();}
    while(ch>=‘0‘&&ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();}
    return x*f;
}
int n,m,k,t,pre[maxn],link[maxn],sccno[maxn],dfs_clock,scc_cnt,cas,bel1[maxn],pk[maxn],dp[maxn],vis[maxn],sum[maxn];
vi e[maxn],to[maxn],bel[maxn];
stack<int>s;
void bfs(int p)
{
    queue<int>q;
    for(int x:bel[p])for(int y:to[x])if(sccno[y]!=p)q.push(y),pk[p]++,vis[sccno[y]]++;
    while(!q.empty())
    {
        int x=q.front();
        q.pop();
        for(int y:to[x])
        {
            q.push(y);
            pk[p]++;
            vis[sccno[y]]=1;
        }
    }
}
void dfs(int u)
{
    pre[u]=link[u]=++dfs_clock;
    s.push(u);
    for(int x:e[u])
    {
        if(!pre[x])
        {
            dfs(x);
            link[u]=min(link[u],link[x]);
        }
        else if(!sccno[x])
        {
            link[u]=min(link[u],pre[x]);
        }
    }
    if(link[u]==pre[u])
    {
        scc_cnt++;
        while(true)
        {
            int x=s.top();
            s.pop();
            sccno[x]=scc_cnt;
            bel[scc_cnt].pb(x);
            bel1[scc_cnt]++;
            if(x==u)break;
        }
    }
}
void find_scc(int n)
{
    dfs_clock=scc_cnt=0;
    memset(sccno,0,sizeof(sccno));
    memset(pre,0,sizeof(pre));
    for(int i=1;i<=n;i++)
        if(!pre[i])dfs(i);
}
int main()
{
    int i,j;
    scanf("%d%d",&n,&m);
    rep(i,1,n)
    {
        int a;
        scanf("%d",&a);
        e[i].pb(a),to[a].pb(i);
    }
    find_scc(n);
    rep(i,1,scc_cnt){pk[i]=bel1[i];if(bel1[i]!=1)bfs(i);}
    dp[0]=1;
    rep(i,1,scc_cnt)
    {
        if(vis[i])continue;
        int x=bel1[i],y=pk[i];
        rep(j,1,m)sum[j]=sum[j-1]+dp[j];
        for(j=m;j>=1;j--)
        {
            if(j<x)break;
            else if(j>=x&&j<=y)dp[j]=1;
            else if(sum[j-x]-sum[j-y-1])dp[j]=1;
        }
    }
    for(i=m;dp[i]==0;i--);
    printf("%d\n",i);
    //system("Pause");
    return 0;
}
时间: 2024-11-05 00:35:55

Outing的相关文章

hihocoder 1154 Spring Outing

传送门 #1154 : Spring Outing 时间限制:20000ms 单点时限:1000ms 内存限制:256MB 描述 You class are planning for a spring outing. N people are voting for a destination out of K candidate places. The voting progress is below: First the class vote for the first candidate p

公司outing选项

Sign up:? 2014 Summer Outing ? 请您从以下三个方案中选择您最感兴趣的一个项目, 如果您不能参加此次summer outing, 请选择"遗憾放弃"- ?报名请点击这里 ? 我们将根据此次报名人数与旅行社签约并按人数付费, 请您仔细考虑后再作出选择,报名截止后将不予更改, 未按时报名的同事按默认放弃处理 ?- 截止日期为:7月31 日 ? Option 1:16 Aug (Sat) 薰衣草+水库山庄休闲一日游? ?????? ?? ?????????????

CodeForcesGym 100502G Outing

Outing Time Limit: 1000ms Memory Limit: 524288KB This problem will be judged on CodeForcesGym. Original ID: 100502G64-bit integer IO format: %I64d      Java class name: (Any) Organising a group trip for the elderly can be a daunting task... Not least

【动态规划】【缩点】NCPC 2014 G Outing

题目链接: http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1793 题目大意: 一辆公交车,上面M个座位,N个人(M<=N<=1000),每个人只有在Ci也上车的情况下才上车.问最多上车几人. 题目思路: [动态规划][缩点] 首先这是一张N个点N条边的有向图.如果J在I也上车的情况下才上车则连一条I到J的边.这样每个点入度最多为1. 这张图有可能有环,所以先缩点,缩完点之后每个环不会有入边,且一定是一个子树的根节点.这样原来的有环的图就变成

CSU1580: Outing(强连通+拓扑排序+dp)

Description Input Output Sample Input 4 4 1 2 3 4 Sample Output 4 HINT Source NCPC 2014 #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,

PAT Spring Outing

首先题目大意为一个班级N位同学投票春游地点,K个候选地,若某个地点投票票数大于一半人数,则选择这个地点,若所有地点都没有被选择则在家呆着. 且每个人都很聪明,投票时会做出最有利与自己的选择. 输入例子为: 2 21 0 22 1 0 第一行为N,K下面N行K+1个数为他们的投票次序很容易陷入一个误区,就是每个人的次序即为他们的喜好次序. In the sample case, if the second peoson vote against the first place, no place

CSU 1580 Outing 强连通+背包

题目链接:点击打开链接 给定n个人,车的载人量m 下面给出a[i]数组 想要邀请i上车,必须先邀请a[i]上车 问:最多能邀请到多少人. 观察得到,这是一个有向图,按照i->a[i]建边后得到的图是类似于树形,但链的尾部是一个简单环. 如下: 5 2 2 3 4 1 4 则我们必须先同时邀请1234,才能邀请5. 所以建立一个反图(即边的方向相反),然后强连通缩点一下,这样就得到了一个森林(多个树的图). 且对于一个树,只有根节点是需要同时邀请的(因为根节点是个环,子节点都是单个点),而子节点是

java面试题大全

java面试笔试题大汇总     第一,谈谈final, finally, finalize的区别. 最常被问到. 第二,Anonymous Inner Class (匿名内部类) 是否可以extends(继承)其它类,是否可以implements(实现)interface(接口)? 第三,Static Nested Class 和 Inner Class的不同,说得越多越好(面试题有的很笼统). 第四,&和&&的区别. 这个问得很少. 第五,HashMap和Hashtable的区

hdu 5868 2016 ACM/ICPC Asia Regional Dalian Online 1001 (burnside引理 polya定理)

Different Circle Permutation Time Limit: 3000/1500 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)Total Submission(s): 208    Accepted Submission(s): 101 Problem Description You may not know this but it's a fact that Xinghai Square is