tyvj1510:专家复仇

背景

外星人完成对S国的考察后,准备返回,可他们的飞碟已经没燃料了……
S国的专家暗自窃喜……复仇的机会终于来了——他们打算敲诈外星人一大笔钱……

描述

S国有n个燃料基地,保存有外星人所需的全部燃料,编号分别为1,2,3,…,n,对于每个燃料基地i,都有【((i-1) mod 10)+1】吨燃料。其中,编号<=5的燃料基地两两之间都有可双向通行的路;对于其余每个燃料基地i,与(i-1),(i-3)之间,也有可双向通行的路。对于任意两燃料基地i,j,若之间有路将他们【直接】连接,则通过这条路的运费为【(i*j)mod10+(i+j)mod6+1)】(单位:元/吨)。
S国的专家要按每吨一元的价格把燃料卖给外星人,并且要它们支付运费。那么,外星人应选择把所有燃料运往那个燃料基地,才能尽可能的让S国专家失望?它们所要支付的最小费用是多少?
注:数据保证解的唯一性。

输入格式

仅有一个整数n。

输出格式

第一行:外星人所要支付的最小费用;
第二行:可供外星人选择的燃料基地的编号。

测试样例1

输入

6

输出

107 
5

备注

样例解释:
第1-5个基地两两间有路,第6个基地与第3,5个基地间有路。当把全部燃料运到第五个基地时,总费用最少,为107.

数据范围:
对于 30%的数据,有5<N<50;
对于 60%的数据,有5<N<500;
对于100%的数据,有5<=N<700;
输出数据范围请大家自行判断。
题解
700弱数据。。谨遵黄学长教诲,用来练打表了
大致程序就是这样,两次打表第二遍输出j就行了
#include<cstdio>
#include<algorithm>
#include<cstring>
#define inf 1<<29
using namespace std;
int a[710],map[710][710];
int link[710][710],b[710];
void floyd(int x)
{
    for(int k=1 ; k<=x ; ++k)
        for(int i=1 ; i<=x ; ++i)
            for(int j=1 ; j<=x ; ++j)
                if(link[i][k]<link[i][j]&&link[k][j]<link[i][j])
                    link[i][j]=min(link[i][j],link[i][k]+link[k][j]);
}
int main()
{
    memset(map,0x7f,sizeof(map));
    for(int i=1 ; i<=700 ; ++i){a[i]=((i-1)%10)+1;b[i]=b[i-1]+a[i];}
    for(int i=1 ; i<=700 ; ++i)
    {
        map[i][i]=0;
        if(i<=5)
        {
            for(int j=i+1 ; j<=5 ; ++j)
                {
                    int t=(i*j)%10+(i+j)%6+1;
                    map[i][j]=map[j][i]=t;    
                }
        }
        else 
        {
            int t=(i*(i-1))%10+(i+i-1)%6+1;
            map[i][i-1]=map[i-1][i]=t;
            t=(i*(i-3))%10+(i+i-3)%6+1;
            map[i][i-3]=map[i-3][i]=t;
        }
    }
    for(int i=1 ; i<=700 ; ++i)
    {
        int ans=inf;
        for(int j=1 ; j<=i ; ++j)
            for(int k=1 ; k<=i ; ++k)
                link[j][k]=map[j][k];
        floyd(i);
        for(int j=1 ; j<=i ; ++j)
            {
                int tmp=0;
                for(int k=1 ; k<=i ; ++k)
                {
                    tmp+=link[j][k]*a[k];
                }
                ans=min(ans,tmp+b[i]);

         /* if(ans>tmp+b[i])
          {
            ans=tmp+b[i];
            fu=j;
          }
          }
          printf("%d,",fu);

            }*/第二个表
        printf("%d,",ans);
    }
    return 0;
 } 

 

 
posted @ 2017-09-11 23:29  傅judge  阅读(140)  评论(0编辑  收藏  举报