codeforces 100753A A Journey to Greece (tsp 问题 + 最短路)

For a long time Tim wanted to visit Greece. He has already purchased his flight to and from Athens. Tim has a list of historical sites he wants to visit, e.g., Olympia and Delphi. However, due to recent political events in Greece, the public transport has gotten a little complicated. To make the Greek happy and content with their new government, many short-range bus and train lines have been created. They shall take the citizens around in their neighborhoods, to work or to their doctor. At the same time, long-range trains that are perfect for tourists have been closed down as they are too expensive. This is bad for people like Tim, who really likes to travel by train. Moreover, he has already purchased the Greece' Card for Public Conveyance (GCPC) making all trains and buses free for him.

Despite his preferred railway lines being closed down, he still wants to make his travel trough Greece. But taking all these local bus and train connections is slower than expected, so he wants to know whether he can still visit all his favorite sites in the timeframe given by his flights. He knows his schedule will be tight, but he has some emergency money to buy a single ticket for a special Greek taxi service. It promises to bring you from any point in Greece to any other in a certain amount of time.

For simplicity we assume, that Tim does never have to wait for the next bus or train at a station. Tell Tim, whether he can still visit all sites and if so, whether he needs to use this taxi ticket.

Input Format

The first line contains five integers NN , PP , MM , GG and TT , where NN denotes the number of places in Greece, PPthe number of sites Tim wants to visit, MM the number of connections, GG the total amount of time Tim can spend in Greece, and T the time the taxi ride takes (1 \le N \le 2\cdot 10^4; 1\le P \le 15;1\le M,G\le 10^5;1\le T \le 500)(1N2104;1P15;1M,G105;1T500).

Then follow PP lines, each with two integers p_ipi and t_iti, specifying the places Tim wants to visit and the time Tim spends at each site (0 \le p_i < N; 1 \le t_i \le 500)(0pi<N;1ti500). The sites p_ipi are distinct from each other.

Then follow MM lines, each describing one connection by three integers s_isid_idi and t_iti, where s_isi and d_idi specify the start and destination of the connection and t_iti the amount of time it takes (0 \le s_i,d_i <N;1 \le t_i \le 500)(0si,di<N;1ti500).

All connections are bi-directional. Tim's journey starts and ends in Athens, which is always the place 00.

Output Format

Print either "impossible", if Tim cannot visit all sites in time, "possible without taxi", if he can visit all sites without his taxi ticket, or "possible with taxi", if he needs the taxi ticket.

样例输入

6 3 10 18 5
1 2
4 2
5 2
0 1 2
1 2 3
2 4 3
1 3 10
2 3 6
0 3 2
3 4 2
4 5 1
3 5 2
0 5 5

样例输出

possible with taxi

题目来源

German Collegiate Programming Contest 2015

思路: p遍最短路求出p个点之间的最短路,跑一个tsp。

代码:

#include<bits/stdc++.h>

using namespace std;
typedef pair<int,int > pii;
const int N =2e4+5;
const int M =2e5+5;
const int inf =0x3f3f3f3f;
const int maxn=17;

struct node
{
    int to;
    int next;
    int w;
}edge[M];

int head[N],tot;
void edge_init()
{
    memset(head,-1,sizeof(head)); tot=0;
}

void add(int u,int v,int w)
{
    edge[++tot].to=v; edge[tot].w=w;
    edge[tot].next=head[u];  head[u]=tot;
}

int n,m,p,G,T;
int city[maxn];
int c_time[maxn];
int hs[N];
int tmpd[N];
int dis[maxn][maxn];
int vis[N];
int zero;

void dij(int st)
{
    memset(vis,0,sizeof(vis));
    memset(tmpd,inf,sizeof(tmpd));
    tmpd[st]=0; vis[st]=1;

    priority_queue<pii,vector<pii>,greater<pii> >q;
    q.push(pii(tmpd[st],st));

    pii tmp;
    int u,v,w;
    while(!q.empty()){
        tmp=q.top(); q.pop();
        u=tmp.second;
        if(tmp.first>tmpd[u]) continue;
        vis[u]=1;

        for(int i=head[u];i!=-1;i=edge[i].next){
            v=edge[i].to;  w=edge[i].w;
            if(vis[v]) continue;
            if(tmpd[v]>tmpd[u]+w){
                tmpd[v]=tmpd[u]+w;
                q.push(pii(tmpd[v],v));
            }
        }
    }
    st=hs[st];
    for(int i=0;i<p;i++){
        dis[st][i]=tmpd[city[i]];
    }
    dis[st][hs[0]]=tmpd[0];
    return ;
}

int dp[65538][17][2];

int main()
{
    scanf("%d %d %d %d %d",&n,&p,&m,&G,&T);
    edge_init();
    zero=0;
    for(int i=0;i<p;i++){
        scanf("%d %d",&city[i],&c_time[i]);
        hs[city[i]]=i;
        if(city[i]==0) zero=1;
    }

    int u,v,w;
    for(int i=1;i<=m;i++){
        scanf("%d %d %d",&u,&v,&w);
        add(u,v,w);
        add(v,u,w);
    }

    if(zero==0)
    {
        hs[0]=p;
        dij(0);
    }
    for(int i=0;i<p;i++){
        dij(city[i]);
    }

    memset(dp,inf ,sizeof(dp));

    for(int i=0;i<p;i++){
        dp[(1<<i)][i][1]=c_time[i]+dis[hs[0]][i];
        dp[(1<<i)][i][0]=c_time[i]+T;
    }

    int sts=(1<<p)-1;
    //cout<<sts<<endl;
    for(int s=1;s<=sts;s++){
        for(int i=0;i<p;i++){
            if(((s>>i)&1)==0) continue;
            for(int j=0;j<p;j++){
                if(((s>>j)&1)) continue;
                dp[s|(1<<j)][j][1]=min(dp[s|(1<<j)][j][1],dp[s][i][1]+c_time[j]+dis[i][j]);
                dp[s|(1<<j)][j][0]=min(dp[s|(1<<j)][j][0],dp[s][i][1]+T+c_time[j]);
                dp[s|(1<<j)][j][0]=min(dp[s|(1<<j)][j][0],dp[s][i][0]+c_time[j]+dis[i][j]);
            }
        }
    }
    int poss=0;
    int flag=0;
    for(int i=0;i<p;i++){
        if(dp[sts][i][1]+dis[i][hs[0]]<=G) flag=1;
        if(dp[sts][i][1]+T<=G) poss=1;
        if(dp[sts][i][0]+dis[i][hs[0]]<=G) poss=1;
    }

    if(flag){
        cout<<"possible without taxi"<<endl;  return 0;
    }
    if(poss){
        cout<<"possible with taxi"<<endl; return 0;
    }
    cout<<"impossible"<<endl;
    return 0;
}

猜你喜欢

转载自blog.csdn.net/yjt9299/article/details/81031830