列表

详情


NC17630. [NOI2010]航空管制

描述

世博期间,上海的航空客运量大大超过了平时,随之而来的航空管制也频频发生。最近,小X就因为航空管制,连续两次在机场被延误超过了两小时。对此,小X表示很不满意。

在这次来烟台的路上,小X不幸又一次碰上了航空管制。于是小X开始思考关于航空管制的问题。

假设目前被延误航班共有n个,编号为1至n。机场只有一条起飞跑道,所有的航班需按某个顺序依次起飞(称这个顺序为起飞序列)。定义一个航班的起飞序号为该航班在起飞序列中的位置,即是第几个起飞的航班。

起飞序列还存在两类限制条件:

· 第一类(最晚起飞时间限制):编号为i的航班起飞序号不得超过ki;

· 第二类(相对起飞顺序限制):存在一些相对起飞顺序限制(a,b),表示航班a的起飞时间必须早于航班b,即航班a的起飞序号必须小于航班b的起飞序号

小X思考的第一个问题是,若给定以上两类限制条件,是否可以计算出一个可行的起飞序列。第二个问题则是,在考虑两类限制条件的情况下,如何求出每个航班在所有可行的起飞序列中的最小起飞序号

输入描述

第一行包含两个正整数n和m,n表示航班数目,m表示第二类限制条件(相对起飞顺序限制)的数目。

第二行包含n个正整数k1, k2, …, kn。

接下来m行,每行两个正整数a和b,表示一对相对起飞顺序限制(a,b),其中1≤a,b≤n, 表示航班a必须先于航班b起飞。

输出描述

第一行包含n个整数t1, t2, …, tn,其中ti表示航班i可能的最小起飞序号,相邻两个整数用空格分隔。

示例1

输入:

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

输出:

3 4 1 2 1 

说明:

在样例1 中:

起飞序列3 5 1 4 2满足了所有的限制条件,所有满足条件的起飞序列有:

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

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

由于存在(5, 1)和(3, 1)两个限制,航班1只能安排在航班5和3之后,故最早起飞时间为3,其他航班类似。

示例2

输入:

5 0
3 3 3 5 5

输出:

1 1 1 4 4 

说明:

虽然航班4、5没有相对起飞顺序限制,但是由于航班1、2、3都必须安排在前3个起飞,所以4、5最早只能安排在第4个起飞。

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++14(g++5.4) 解法, 执行用时: 412ms, 内存消耗: 740K, 提交时间: 2019-08-20 21:54:38

#include<bits/stdc++.h>

#define FOG(x,y,z) for(register int x=y,x##_=z;x<=x##_;++x)
#define DOG(x,y,z) for(register int x=y,x##_=z;x>=x##_;--x)
#define FOR(x,y,z) for(int x=y,x##_=z;x<=x##_;++x)
#define DOR(x,y,z) for(int x=y,x##_=z;x>=x##_;--x)
#define FOR_(x,y,z,s) for(int x=y,x##_=z;x<=x##_;x+=s)
#define FOR__(x,y,z) for(int x=y,x##_=z;x<=x##_;x<<=1)
#define EOR(x,y) for(int x##_=head[x],y=edge[x##_].e;x##_;y=edge[x##_=edge[x##_].to].e)
#define EGOR(x,y,z) for(int x##_=head[x],y=edge[x##_].e,z=edge[x##_].c;x##_;y=edge[x##_=edge[x##_].to].e,z=edge[x##_].c)

#define clr(x,y) memset(x,y,sizeof(x))
#define cpy(x,y) memcpy(x,y,sizeof(x))
#define szf(x) sizeof(x)
#define min3(x,y,z) min(min(x,y),z)
#define max3(x,y,z) max(max(x,y),z)

#define read2(x,y) read(x),read(y)
#define read3(x,y,z) read(x),read(y),read(z)
#define read4(x,y,z,w) read3(x,y,z),read(w)
#define reads(str) sf("%s",str)

#define ts (*this)
#define sf scanf
#define pf printf

#define ll long long
#define ull unsigned long long
#define db long double
#define ct clock_t
#define ck() clock()
#define rd rand()
#define rmx RAND_MAX
#define RD T*(rd*2-rmx)


using namespace std;

template<class T>bool tomin(T &x,T y){return y<x?x=y,1:0;}
template<class T>bool tomax(T &x,T y){return x<y?x=y,1:0;}
template<class T>void read(T &x){
	char c;
	x=0;
	int f=1;
	while(c=getchar(),c<'0'||c>'9')if(c=='-')f=-1;
	do x=(x<<3)+(x<<1)+(c^48);
	while(c=getchar(),c>='0'&&c<='9');
	x*=f;
}

const db Pi=acos(-1);
const int maxn=2005;
const int maxm=10005;
int n,m;
int A[maxn];
namespace P30{
	bool eg[maxn][maxn];
	bool vis[maxn];
	int s[maxn];
	bool ans;
	int mn[maxn];
	int res[maxn];
	bool Check(int x,int p){
		if(vis[x])return 0;
		if(p>A[x])return 0;
		FOR(i,1,p-1)if(eg[x][s[i]])return 0;
		return 1;
	}
	void dfs(int x){
		if(x==n+1){
			if(!ans)FOR(i,1,n)res[i]=s[i];
			ans=1;
			FOR(i,1,n)tomin(mn[s[i]],i);
			return;
		}
		FOR(i,1,n)if(Check(i,x)){
			vis[i]=1;
			s[x]=i;
			dfs(x+1);
			vis[i]=0;
		}
	}
	void solve(){
		int x,y;
		FOR(i,1,m){
			read2(x,y);
			eg[x][y]=1;
		}
		clr(mn,67);
		dfs(1);
		FOR(i,1,n){
            pf("%d",mn[i]);
            if(i<n)putchar(' ');
        }
	}
}
namespace P100{
	struct Edge{
		int e,to;
	}edge[maxm];
	int deg[maxn],Deg[maxn];
	int head[maxn],tot;
	void Add(int x,int y){
		edge[++tot]=(Edge){y,head[x]};
		head[x]=tot;
		Deg[y]++;
	}
	struct node{
		int u,v;
		bool operator <(const node &A)const
		{
			return v<A.v;
		}
	}V[maxn];
	priority_queue<node>q;
	int stk[maxn],top;
	int solve(int s){
		cpy(deg,Deg);
		deg[s]=n;
		while(!q.empty())q.pop();
		FOR(i,1,n)if(!deg[i])q.push(V[i]);
		int p=n;
		while(!q.empty()){
			int u=q.top().u,v=q.top().v;q.pop();
			if(v<p)return p;
			p--;
			EOR(u,v)if(!(--deg[v]))q.push(V[v]);
		}
		return p;
	}
	void solve(){
		int x,y;
		FOR(i,1,n)V[i]=(node){i,A[i]};
		while(m--){
			read2(x,y);
			Add(y,x);
		}
		cpy(deg,Deg);
		FOR(i,1,n)if(!deg[i])q.push(V[i]);
		while(!q.empty()){
			int u=q.top().u;q.pop();
			stk[++top]=u;
			EOR(u,v)if(!(--deg[v]))q.push(V[v]);
		}
		FOR(i,1,n){
            pf("%d",solve(i));
            if(i<n)putchar(' ');
        }
	}
}
int main(){
	srand(time(NULL));
	read2(n,m);
	FOR(i,1,n)read(A[i]);
	if(n<=10)P30::solve();
	else P100::solve();
	return 0;
}

C++(clang++11) 解法, 执行用时: 343ms, 内存消耗: 584K, 提交时间: 2020-10-22 12:41:10

#include<bits/stdc++.h>
#define LL long long
#define pb push_back
#define pii pair<int,int>
using namespace std;
const int N=2e3+5;
int n,m,a[N],c[N],deg[N],id[N],dfn;bool vis[N];
vector<int>adj[N],Ans;
priority_queue<pii>q;
int getans(int x){
	while(!q.empty())q.pop();
	memcpy(deg,c,sizeof(deg));
	for(int i=1;i<=n;i++)if(!deg[i])q.push(pii(a[i],i));
	int tot=0;
	while(!q.empty()){
		int u=q.top().second;q.pop();
		if(u==x)continue;
		if(n-tot>a[u])return n-tot;
		tot++;
		for(auto v:adj[u]){deg[v]--;if(!deg[v])q.push(pii(a[v],v));}
	}
	return n-tot;
}
int main(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)scanf("%d",&a[i]);
	for(int i=1,u,v;i<=m;i++)scanf("%d%d",&u,&v),adj[v].pb(u),deg[u]++;
	memcpy(c,deg,sizeof(c));
	for(int i=1;i<=n;i++)if(!deg[i])q.push(pii(a[i],i));
	while(!q.empty()){
		int u=q.top().second;q.pop();Ans.pb(u);
		for(auto v:adj[u]){deg[v]--;if(!deg[v])q.push(pii(a[v],v));}
	}
	reverse(Ans.begin(),Ans.end());
	//for(auto u:Ans)printf("%d ",u);puts("");
	for(int i=1;i<=n;i++)printf("%d%c",getans(i)," \n"[i==n]);
	return 0;
}

上一题