题目链接
http://acm.hdu.edu.cn/showproblem.php?pid=1224
题意
从1走到n+1,保证只有一条最长路,且不会存在标号大的点指向标号小的点。输出从1到n+1的最长路径。
思路
反向建图,从n+1跑SPFA求最长路。输出即可。
#include<cstdio>
#include<queue>
#include<iostream>
#include<vector>
#include<map>
#include<cstring>
#include<string>
#include<set>
#include<stack>
#include<algorithm>
#define cle(a) memset(a,0,sizeof(a))
#define inf(a) memset(a,0x3f,sizeof(a))
#define ll long long
#define Rep(i,a,n) for(int i=a;i<=n;i++)
using namespace std;
#define INF2 9223372036854775807ll
const int INF = ( 2e9 ) + 2;
const ll maxn = 110;
int p[maxn],d[maxn],pre[maxn],vis[maxn];
vector<int> g[maxn];
void SPFA(int s,int n)
{
for(int i=1;i<=n+1;i++)d[i]=-INF;
memset(vis,0,sizeof(vis));
queue<int> q;
q.push(s);
vis[s]=1;
d[s]=0;
while(!q.empty())
{
int u=q.front();q.pop();
vis[u]=0;
for(int i=0,L=g[u].size();i<L;i++)
{
int v=g[u][i];
if(d[v]<d[u]+p[v])
{
d[v]=d[u]+p[v];
pre[v]=u;
if(!vis[v])
{
vis[v]=1;
q.push(v);
}
}
}
}
}
int main()
{
int t;
scanf("%d",&t);
for(int T=1;T<=t;T++)
{
int n,m;
scanf("%d",&n);
memset(pre,-1,sizeof(pre));
for(int i=1;i<=n;i++)g[i].clear();
for(int i=1;i<=n;i++)
scanf("%d",&p[i]);
p[n+1]=0;
scanf("%d",&m);
for(int i=0;i<m;i++)
{
int u,v;
scanf("%d%d",&u,&v);
g[v].push_back(u);
}
SPFA(n+1,n);
if(T!=1)puts("");
printf("CASE %d#\n",T);
printf("points : %d\n",d[1]);
printf("circuit : ");
for(int i=1;i!=-1;i=pre[i])
{
if(i==1)
printf("%d",i);
else
{
if(i!=n+1)
printf("->%d",i);
else
printf("->%d",1);
}
}
printf("\n");
}
}