Light oj 1316 - A Wedding Party(状压dp)

来源:互联网 发布:python爬虫框架scrapy 编辑:程序博客网 时间:2024/05/21 17:06

1316 - A Wedding Party
PDF (English)StatisticsForum
Time Limit: 3 second(s)Memory Limit: 32 MB

We all know that we have a big and exciting wedding party ahead. So we made a plan to go to buy a gift for the wedding party. We all gathered at a place and we were just about to buy the gift. Unfortunately, we find that we have a 'Team Practice Contest' ahead. Now before going to the contest we have to buy the gift. As time is too short we will try to buy the gift on the way to the contest. We will try to visit as many shops as possible. The city map is represented by a graph with N nodes and M edges. N nodes represent the N junctions and M edges represent the M unidirectional roads connecting the cities. Every road has a cost which represents the required time to use the road. The contest is running at junction N-1 and we will start our journey at junction 0. And there are exactly Sshops located at different junctions.

Now given the location of the shops you have to find the route from junction 0 to junction N-1 which will visit maximum number of shops with minimum time (first maximize the number of shops then minimize the time to visit them). We can visit a junction more than once.

Input

Input starts with an integer T (≤ 50), denoting the number of test cases.

Each case begins with three non negative integers N (2 ≤ N ≤ 500)M (1 ≤ M ≤ 10000) S (0 ≤ S ≤ 15). Next line contains S integers denoting the shop locations. Each of the next M lines contains three integers uv, w (0 < u, v < N, u ≠ v, 1 ≤ w ≤ 100) denoting a road from u to with cost w.

Output

For each case of input you have to print the case number and two integers representing maximum number of shops we can visit in the way and the minimum time required to reach junction N-1 after visiting maximum number of shops. If we cannot attend the contest, print "Impossible". See samples for more details.

Sample Input

Output for Sample Input

2

4 4 4

0 1 2 3

0 1 10

1 3 30

0 2 30

2 3 5

4 4 4

0 1 2 3

0 1 10

3 1 30

0 2 30

3 2 5

Case 1: 3 35

Case 2: Impossible

 


PROBLEM SETTER: MUHAMMAD RIFAYAT SAMEE
SPECIAL THANKS: JANE ALAM JAN

#pragma comment(linker, "/STACK:1024000000,1024000000")#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<cmath>#include<queue>#include<stack>#include<vector>#include<map>#define L(x) (x<<1)#define R(x) (x<<1|1)#define MID(x,y) ((x+y)>>1)#define bug printf("hihi\n")#define eps 1e-12typedef long long ll;using namespace std;#define INF 0x3f3f3f3f#define N 505int a[N][N];int dis[N][N];int dp[1<<18][18];int n,m,k;vector<int>g;int d[N];int vis[N];int ca=0;bool inin;bool ininin;int ans[N];void dij(int s){   int i,j;   memset(d,INF,sizeof(d));   d[s]=0;   memset(vis,0,sizeof(vis));   for(i=0;i<n;i++)   {       int now,temp=INF;       for(j=0;j<n;j++)         if(d[j]<temp&&!vis[j])       {           now=j;           temp=d[j];       }       if(temp>=INF) return ;       vis[now]=1;       for(int j=0;j<n;j++)          if(!vis[j]&&a[now][j]<INF)             d[j]=min(d[j],d[now]+a[now][j]);   }}void inint(){    int i,j;    memset(dis,INF,sizeof(dis));    if(!inin)   g.push_back(0);    if(!ininin)  g.push_back(n-1);    sort(g.begin(),g.end());    for(i=0;i<g.size();i++)    {        dij(g[i]);        for(j=0;j<g.size();j++)            dis[i][j]=d[g[j]];    }}int get(int cur){   int i,j;   int t=0;   for(i=0;i<=k;i++)     if(cur&(1<<i))     {        if(i==0&&inin) t++;        if(i!=0&&i!=k) t++;        if(i==k&&ininin) t++;     }     return t;}bool DP(){    int i,j;    k=g.size()-1;    memset(dp,INF,sizeof(dp));    dp[1][0]=0;    int len=1<<(k+1);    for(int cur=1;cur<len;cur++)        for(i=0;i<=k;i++)       {        if(!cur&(1<<i)) continue;        if(dp[cur][i]>=INF) continue;        for(int j=0;j<=k;j++)        {            if(cur&(1<<j)) continue;            if(dis[i][j]>=INF) continue;            int to=cur|(1<<j);            dp[to][j]=min(dp[to][j],dp[cur][i]+dis[i][j]);        }    }   memset(ans,INF,sizeof(ans));   for(i=0;i<len;i++)   {       if(dp[i][k]>=INF) continue;       int t=get(i);       ans[t]=min(ans[t],dp[i][k]);   }   for(i=k+k;i>=0;i--)      if(ans[i]<INF)      {          printf("Case %d: %d %d\n",++ca,i,ans[i]);          return true;      }   return false;}int main(){   int i,j,t;   ca=0;   scanf("%d",&t);   while(t--)   {       scanf("%d%d%d",&n,&m,&k);       memset(a,INF,sizeof(a));       inin=false;       ininin=false;       g.clear();       int x;       for(i=0;i<k;i++)       {           scanf("%d",&x);           if(x==0) inin=true;           if(x==n-1) ininin=true;           g.push_back(x);       }       int u,v,len;       while(m--)       {           scanf("%d%d%d",&u,&v,&len);           if(a[u][v]>len) a[u][v]=len;       }        inint();        if(!DP())         printf("Case %d: Impossible\n",++ca);   }   return 0;}




0 0
原创粉丝点击