题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=1

记录路径不会,于是又拜访了一下各个牛人的博客,真是惭愧。。无奈牛人都是用DP做的。。。sad。。。好不容易找到一个用spfa做的,写的乱七八糟。。不不。。是写的很高级,连加边都写得那么高级,实在看不懂,。不过有了思路。于是现学的spfa。。记录路径其实就是在松弛的过程中记录路径。然后在最后最短路求完后再回溯,把路径求出来。然后输出即可。这题调试了好长时间。。。终于调试成功了。。


#include <iostream>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <ctype.h>
#include <queue>
#include <map>
#include<algorithm>

using namespace std;
int n, m, vis[200], d[200], head[200], maxint=0,p[200], per[200],lu[200], cnt;
struct node
{
    int v, w, next;
}edge[10000];
void add(int u, int v, int w)
{
    edge[cnt].v=v;
    edge[cnt].w=w;
    edge[cnt].next=head[u];
    head[u]=cnt++;
}
void spfa(int s)
{
    int i;
    queue<int>q;
    for(i=0;i<=n;i++)
        d[i]=maxint;
    d[s]=0;
    vis[s]=1;
    q.push(s);
    while(!q.empty())
    {
        int f=q.front();
        q.pop();
        vis[f]=0;
        for(i=head[f];i!=-1;i=edge[i].next)
        {
            if(d[edge[i].v]<edge[i].w+d[f])
            {
                d[edge[i].v]=edge[i].w+d[f];
                //printf("%d %d\n",edge[i].v,d[edge[i].v]);
                per[edge[i].v]=f;
                //printf("%d %d\n",edge[i].v,f);
                if(!vis[edge[i].v])
                {
                    vis[edge[i].v]=1;
                    q.push(edge[i].v);
                }
            }
        }
    }
}
int main()
{
    int t, i, a, b, num=0, j;
    scanf("%d",&t);
    while(t--)
    {
        num++;
        memset(head,-1,sizeof(head));
        memset(vis,0,sizeof(vis));
        memset(edge,0,sizeof(edge));
        scanf("%d",&n);
        for(i=1;i<=n;i++)
        {
            scanf("%d",&p[i]);
        }
        p[++n]=p[1];
        scanf("%d",&m);
        while(m--)
        {
            scanf("%d%d",&a,&b);
            if(a>b)
            {
                int t=a;
                a=b;
                b=t;
            }
            add(a,b,p[b]);
        }
        cnt=0;
        spfa(1);
        printf("CASE %d#\n",num);
        printf("points : %d\n",d[n]);
        printf("circuit : 1");
        cnt=0;
        /*for(i=1;i<=n;i++)
            printf("%d ",per[i]);
        printf("\n");*/
        for(j=per[n];j!=1;j=per[j])
        {
            lu[cnt++]=j;
        }
        for(j=cnt-1;j>=0;j--)
        {
            printf("->%d",lu[j]);
        }
        printf("->1\n");
        if(t!=0)
            printf("\n");
    }
    return 0;
}