您的位置:首页 > 其它

poj 1949 Chores

2013-04-14 19:40 204 查看
说说思路:
有点像拓扑排序。in[i]表示i的入度,st[i]表示i的开始时间。
把入度为0的点压入队列中,每次读出一个点u,然后去更新以他为前驱的点j st[j]=max(st[j],st[u]+a[u])
in[j]--.即把j点入度减去1,如果j点的开始时间比u点的结束时间还小,就更新j点的开始时间。如果j点入度为0再压入队列。

#include <iostream>
#include <stdio.h>
#include <string.h>
using namespace std;
const int maxn=10000+10;
int a[maxn],in[maxn],st[maxn],que[maxn],head[maxn];
int n,lon;
struct
{
int next,to;
}e[maxn*100];

void edgeini()
{
memset(head,-1,sizeof(head));
lon=0;
}

void edgemake(int from,int to)
{
e[++lon].to=to;
e[lon].next=head[from];
head[from]=lon;
}

int work()
{
int ans=0;
int front=1,end=0;
for(inti=1;i<=n;i++)
if(in[i]==0)
{
que[++end]=i;
}
while(front<=end)
{
int u=que[front++];
for(int k=head[u];k!=-1;k=e[k].next)
{
intv=e[k].to;
in[v]--;
st[v]=max(st[v],st[u]+a[u]);
if(in[v]==0)
que[++end]=v;
}
ans=max(ans,st[u]+a[u]);
}
return(ans);
}

int main()
{
edgeini();
scanf("%d",&n);
for(inti=1;i<=n;i++)
{
scanf("%d",&a[i]);
int tmp,from;
scanf("%d",&tmp);
for(int j=1;j<=tmp;j++)
{
scanf("%d",&from);
edgemake(from,i);
in[i]++;
}
}
int ans=work();
printf("%d\n",ans);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: