洛谷 [P1113] 杂务
图论的做法是topsort
一看见有序我们就想到了DAG图,于是用topsort做,对于每一个加入队列的顶点,都用它的时间去更新它所指向的点的时间,本质上仍是DP的思想,dp[i]=max{dp[j]}+ti[i] (j->i).
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <cmath>
#include <queue>
using namespace std;
const int MAXN=10005;
int init(){
int rv=0,fh=1;
char c=getchar();
while(c<'0'||c>'9'){
if(c=='-') fh=-1;
c=getchar();
}
while(c>='0'&&c<='9'){
rv=(rv<<1)+(rv<<3)+c-'0';
c=getchar();
}
return rv*fh;
}
struct edge{
int to,nxt;
}e[MAXN*100];
int head[MAXN],nume,n,ti[MAXN],inn[MAXN],ans,dp[MAXN];
queue<int >q;
bool f[MAXN];
void adde(int from,int to){
e[++nume].to=to;
e[nume].nxt=head[from];
head[from]=nume;
}
int main(){
freopen("in.txt","r",stdin);
n=init();
for(int i=1;i<=n;i++){
int t=init();
t=init();
ti[i]=t;
t=init();
while(t){
adde(t,i);
inn[i]++;
t=init();
}
}
for(int i=1;i<=n;i++){
if(!inn[i]) {q.push(i);dp[i]=ti[i];f[i]=1;}
}
while(!q.empty()){
int u=q.front();
q.pop();
if(!head[u]) ans=max(ans,dp[u]);
else for(int i=head[u];i;i=e[i].nxt){
int v=e[i].to;
dp[v]=max(dp[v],dp[u]+ti[v]);
inn[v]--;
if(!inn[v]&&!f[v]) {q.push(v);f[v]=1;}
}
}
cout<<ans;
/*for(int i=1;i<=n;i++){
printf("%d ",dp[i]);
}*/
fclose(stdin);
return 0;
}
本题的特殊之处在于输入已经排好了序,所以可以便输入边DP。
#include<cstdio>
using namespace std;
int f[10001]={0};
int main()
{
int n;
scanf("%d",&n);
for(int i=1;i<=n;++i)
{
int x,t,max=0;
scanf("%*d%d%d",&t,&x);
while(x!=0)
{
max=f[x]>max?f[x]:max;
scanf("%d",&x);
}
f[i]=t+max;
}
int max=0;
for(int i=1;i<=n;++i)
max=f[i]>max?f[i]:max;
printf("%d",max);
return 0;
}