HDU 1224 Free DIY Tour


リンク:
 http://acm.hdu.edu.cn/showproblem.php?pid=1224
タイトル:
Free DIY Tour
Time Limit:2000/1000 MS(Java/Others)    メモリLimit:65536/32768 K(Java/Others)Total Submission(s):1894    Acceepted Submission(s):619
Problem Description
Weiwei is a software enginer of ShinngSoft.He has just excell lently fulfilled a software project with his fellowworks.His so satisfied with their job that he decide to provide the a free therever.good.good。it's the first time to go abroad so they decide to make a collective tour.
The tour commpany shows them a new kind of tour circuit-DIY circuuit.Each cirrcuuit contains some cities which can be selected by tourists themselves.Accoording to commpany's statitititititititic,eacicicicicicicicitytytytytytytytytytyStStinininininininininininininininininininininininststststststststststststininininininininininininininininininininininininininininininininststststststststststを選択します。Not.Not any twowoties in the world have strereight the tourcommpany provide a map to tell it its touristswheheheher they can got a stststraight between any ttwoties on themap.Inordeto ft the map.Inordeto fitititititititititititititititititititititititititititt the themap.Intrtrtrtrtrtrtrtrtrtrititititititititititititititititititititititititititititititititititititititititititititititititititititis,they maked each city on the map with one number、a city with higher number hasのstright flight to a city with lower number. 
Note:Weiwei always starts from Hangzhoo(in this proble、we asume Hangzhou is always the first city and also the last city、so we mark Hangzhou both 
1 and
N+1)、and its interesting point is always 0.
Now as the leader of the team,Weiwei wants to make a tour as interesting as possible.If you were Weiwei,how did you DIY it?
 
Input
The input will contain several cases.The first line is an integer T which suggas the number of cases.The n T cases follows.
Each case will begin with an integer N(2≦N≦100)which is the number of cities on the map.
The n N integers follows,representing the interesting point list of the cities.
And then it is an integer Mフォロワーby M pairs of integers[Ai,Bi](1≦i≦M).Each pair of[Ai,Bi]indicates that a straight fret is available from Cit Ai to City Bi.
 
Output
For each case,your task is to output the maximal summation of interesting points Weiwei and his fellows works can get through optimal DIYing and the optimail circut.The formas as the sample.Youmathase 
Output a blank line between two cases.
 
Sample Input
 
   
2 3 0 70 90 4 1 2 1 3 2 4 3 4 3 0 90 70 4 1 2 1 3 2 4 3 4
 

Sample Output
 
   
CASE 1# points : 90 circuit : 1->3->1 CASE 2# points : 90 circuit : 1->2->1
 




分析与总结:
有点像TSP问题,但是这题已经告诉我们会把最终回来到1的那点看成是n+1点。所以直接当作是求1~n+1的最长路即可。这题还要保存路径。
用单源最短路算法或者用我刚刚学到的Floyd记录路径方法均可。
输出时需要注意,当输出n+1时要把它变成输出1.


代码:

1.  SPFA
#include
#include
#include
#include
using namespace std;

const int INF = 0xfffffff;
const int VN  = 105;

int n,m;
int w[VN][VN];
int point[VN];
int d[VN];
int pre[VN];
bool inq[VN];
int ans[VN];

void init(){
    point[n] = 0;
    for(int i=0; i<=n; ++i){
        w[i][i] = INF;
        for(int j=i+1; j<=n; ++j)
            w[i][j]=w[j][i]=INF;
    }
}

void SPFA(int src){
    memset(inq, 0, sizeof(inq));
    memset(pre, -1, sizeof(pre));
    for(int i=1; i<=n; ++i) d[i]=-INF;
    d[src] = 0;
    queueq;
    q.push(src);
    while(!q.empty()){
        int u = q.front(); q.pop();
        inq[u] = false;
        for(int v=1; v<=n; ++v)if(w[u][v]!=INF){
            int tmp = d[u] + w[u][v];
            if(d[v] < tmp){
                d[v] = tmp;
                pre[v] = u;
                if(!inq[v]){
                    inq[v] = true;
                    q.push(v);
                }
            }
        }
    }
}

void print_path(int u){
    if(pre[u]==-1){
        printf("1");
        return;
    }
    print_path(pre[u]);
    if(u==n) printf("->%d",1);
    else printf("->%d",u);
}

int main(){
    int T,u,v,cas=1;
    scanf("%d",&T);
    while(T--){
        scanf("%d",&n);
        ++n;
        init();
        for(int i=1; i
2.Floyd
#include
#include
#include
#include
using namespace std;

const int INF = -0xfffffff;
const int VN  = 105;

int n,m;
int w[VN][VN];
int path[VN][VN];
int point[VN];
int d[VN];
bool inq[VN];
int ans[VN];

void init(){
    point[n] = 0;
    for(int i=0; i<=n; ++i){
        for(int j=1; j<=n; ++j){
            if(i==j) w[i][j]=0;
            else w[i][j]=INF;
            path[i][j] = j;
        }
    }
}

void Floyd(){
    for(int k=1; k<=n; ++k)
    for(int i=1; i<=n; ++i)
    for(int j=1; j<=n; ++j)if(w[i][k]!=INF && w[k][j]!=INF){
        int tmp=w[i][k]+w[k][j];
        if(w[i][j] < tmp){
            w[i][j] = tmp;
            path[i][j] = path[i][k];
        }
    }
}
int main(){
    int T,u,v,cas=1;
    scanf("%d",&T);
    while(T--){
        scanf("%d",&n);
        ++n;
        init();
        for(int i=1; i%d", path[u][n]==n?1:path[u][n]);
            u=path[u][n];
        }
        puts("");
    }
    return 0;
}
—— 生命の意味は、それに意味を与えることにある。
          
     オリジナル http://blog.csdn.net/shuangde800 , By  D_Double (転載は明記してください)