您的位置:首页 > 其它

noi 2010 航空管制 贪心

2012-07-09 11:58 459 查看
【问题描述】

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

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

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

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

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

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

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

思路:核心是求出每个点最晚出发时间

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
#define MAXN 2001
#define MAXM 100001
#define INF 987654321
struct node
{
int num;
node *next;
};
node *graph[MAXN],memo[MAXM];
int w[MAXN],finish[MAXN];
bool use[MAXN];
bool map[MAXN][MAXN];
int n,m,top=0,label=0;
pair<int,int> sorted[MAXN];
void add(int x,int y)
{
node *p=&memo[top++];
p->num=y; p->next=graph[x]; graph[x]=p;
}
void topo(int x)
{
use[x]=1;
for(node *p=graph[x];p;p=p->next)
if(!use[p->num])
topo(p->num);
finish[++label]=x;
}
void dfs(int x,int u)
{
use[u]=1;
map[x][u]=1;
for(node *p=graph[u];p;p=p->next)
if(use[p->num]==0)
dfs(x,p->num);
}
void make()
{
int i;
for(i=n;i>0;i--)
{
int u=finish[i];
for(node *p=graph[u];p;p=p->next)
w[p->num]=min(w[p->num],w[u]-1);
}
for(i=1;i<=n;i++)
sorted[i]=make_pair(w[i],i);
sort(sorted+1,sorted+n+1);
for(i=1;i<n;i++)
printf("%d ",sorted[i].second);
printf("%d\n",sorted
.second);
}

void solve(int x)
{
int i,j=n;
for(i=n;i>0;i--)
{
int u=sorted[i].second;
if(map[x][u]==0&&w[u]>=j)
j--;
else if(w[u]<j)
break;
}
printf("%d ",j);
}
int main()
{
//freopen("plane10.in","r",stdin);
//freopen("plane.out","w",stdout);
memset(map,0,sizeof(map));
memset(use,0,sizeof(use));
memset(graph,0,sizeof(graph));
scanf("%d%d",&n,&m);
int i;
int x,y;
for(i=1;i<=n;i++)
scanf("%d",w+i);
for(i=1;i<=m;i++)
{
scanf("%d%d",&x,&y);
add(y,x);
}
for(i=1;i<=n;i++)
if(use[i]==0)
topo(i);
make();
for(i=1;i<=n;i++)
{
memset(use,0,sizeof(use));
dfs(i,i);
}
for(i=1;i<=n;i++)
solve(i);
printf("\n");
return 0;
}


P.S. bzoj又挂了
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: