题意:1-n个城市。每个城市有一个有趣值,没有从标号高的城市飞往低城市的直达航班。可以从标号高的城市飞到1。这是1则为n+1。问总共的有趣值是多少。首先输入T;每个T 第一行输入n。下一行是n个城市的有趣值。接下来一个m,代表m个直飞有向航班。
首先此题 没有从标号高的城市飞往低城市的直达航班 说明无环。
题目没说有趣值正负,要用spfa。
行走的边的费用:val[to]。
路径输出:path[y]=x; 表示从 1 到达y的经过的最后一个城市 当然不考虑 y 。
#include <cstdio>
#include <queue>
#include <cstring>
#define m(a,b) memset(a,b,sizeof a)
using namespace std;
const int N=105;
const int INF=0x3f3f3f3f;
int head[N],d[N],path[N],tmp[N],val[N];
bool vis[N];
int n,m,tot;
struct Edge{int to,len,nex;}edge[N*N+2];
void add(int from,int to,int len)
{
edge[++tot]=(Edge){to,len,head[from]};head[from]=tot;
}
queue<int>q;
void spfa(int s)
{
while(!q.empty())
q.pop();
m(vis,0);
m(d,-INF);
m(path,-1);
d[s]=0;
q.push(s);
vis[s]=1;
while(!q.empty())
{
int x=q.front();
q.pop();
vis[x]=0;
for(int i=head[x];i;i=edge[i].nex)
{
int y=edge[i].to,l=edge[i].len;
if(d[y]<d[x]+l)
{
d[y]=d[x]+l;
path[y]=x;
if(!vis[y])
{
vis[y]=1;
q.push(y);
}
}
}
}
}
void print(int cas)
{
printf("CASE %d#\n",cas);
printf("points : %d\n",d[n+1]);
printf("circuit : ");
int cnt=0,u=n+1;
while(path[u]!=-1)
{
tmp[++cnt]=path[u];
u=path[u];
}
printf("1");
for(int i=cnt-1;i>=1;i--)
printf("->%d",tmp[i]);
printf("->1");
puts("");
}
int main()
{
int T,cas=0;
scanf("%d",&T);
bool flag=0;
while(T--)
{
++cas;
m(head,0);
tot=1;
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&val[i]);
val[n+1]=val[1];
scanf("%d",&m);
while(m--)
{
int from,to;
scanf("%d%d",&from,&to);
add(from,to,val[to]); //将点的有趣值转化为边的长度。
}
spfa(1);
if(flag)
puts("");
if(!flag)
flag=1;
print(cas);
}
}