您的位置:首页 > 其它

POJ 3249 Test For Job

2011-02-14 22:13 316 查看
求入度为0的点到出度为0的点的最长路

题目中已经说明了没有环,所以是DAG图,可以拓扑排序+DP解决,复杂度为O(E)

一开始想DFS的,TLE,究其原因,图中的交叉链可能比较多,导致有些边被多次重复搜索

另外,进行拓扑排序时,只有当一个点的入度减为0时才会将它入队列,也就是说当它的前驱节点都访问过以后才会访问它,这也保证了可以用DP解决

代码:

#include<iostream>
#include<cstdio>
#include<memory.h>
#include<queue>
using namespace std;
const int MAX=100005;
const int inf=1<<30;
struct node
{
int v,next;
}g[MAX*20];
int e,n,m;
int adj[MAX],ind[MAX],out[MAX],val[MAX],dp[MAX];
void topsort()
{
queue<int>que;
int i,j,u,v;
for(i=1;i<=n;i++)
{
if(ind[i]==0)
{
que.push(i);
dp[i]=val[i];
}
}
while(!que.empty())
{
u=que.front();
que.pop();
for(i=adj[u];i!=-1;i=g[i].next)
{
v=g[i].v;
if(dp[v]<dp[u]+val[v])
{
dp[v]=dp[u]+val[v];
}
if(--ind[v]==0)
que.push(v);
}
}
}
int main()
{
int i,j;
while(scanf("%d%d",&n,&m)!=EOF)
{
e=0;
memset(adj,-1,sizeof(adj));
memset(ind,0,sizeof(ind));
memset(out,0,sizeof(out));
for(i=1;i<=n;i++)
{
dp[i]=-inf;
scanf("%d",&val[i]);
}
while(m--)
{
scanf("%d%d",&i,&j);
out[i]++;
ind[j]++;
g[e].v=j;
g[e].next=adj[i];
adj[i]=e++;
}
topsort();
int ans=-inf;
for(i=1;i<=n;i++)
{
if(out[i]==0&&dp[i]>ans)
ans=dp[i];
}
cout<<ans<<endl;
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: