Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 6440 | Accepted: 2381 |
Description
A network of m roads connects N cities (numbered from 1 to N). There may be more than one road connecting one city with another. Some of the roads are paid. There are two ways to pay for travel on a paid road i from city ai to city bi:
- in advance, in a city ci (which may or may not be the same as ai);
- after the travel, in the city bi.
The payment is Pi in the first case and Ri in the second case.
Write a program to find a minimal-cost route from the city 1 to the city N.
Input
The first line of the input contains the values of N and m. Each of the following m lines describes one road by specifying the values of ai, bi, ci, Pi, Ri (1 ≤ i ≤ m). Adjacent values on the same line are separated by one or more spaces. All values are integers, 1 ≤ m, N ≤ 10, 0 ≤ Pi , Ri ≤ 100, Pi ≤ Ri (1 ≤ i ≤ m).
Output
The first and only line of the file must contain the minimal possible cost of a trip from the city 1 to the city N. If the trip is not possible for any reason, the line must contain the word ‘impossible’.
Sample Input
4 5 1 2 1 10 10 2 3 1 30 50 3 4 3 80 80 2 1 2 10 10 1 3 2 10 50
Sample Output
110
Source
题目大意:N个城市,m条路线,路线是有向的,每条路线以a b c P R表示
从a出发直接到c花费R 如果之前到达过b那么花费为P
in advance那句研究半天= =一直以为是先到c再到b..没理解出来这个意思……
因为城市数量很少,所以可以开一个二维数组,表示到第i个城市,遍历过某些城市后的最少费用,遍历过的城市通过状压,变成二进制表示即可
这样暴力搜出来就行了
代码如下:
#include <iostream>
#include <cmath>
#include <vector>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <queue>
#include <stack>
#include <list>
#include <algorithm>
#include <map>
#include <set>
#define LL long long
#define Pr pair<int,int>
#define fread() freopen("in.in","r",stdin)
#define fwrite() freopen("out.out","w",stdout)
using namespace std;
const int INF = 0x3f3f3f3f;
const int msz = 10000;
const int mod = 1e9+7;
const double eps = 1e-8;
int mp[11][11][11];
int dis[11][1024];
bool vis[11];
int n,m,tot;
void spfa()
{
memset(dis,INF,sizeof(dis));
memset(vis,0,sizeof(vis));
queue <int> q;
q.push(1);
dis[1][1] = 0;
int u;
while(!q.empty())
{
u = q.front();
q.pop();
vis[u] = 0;
for(int i = 1; i <= n; ++i)
{
if(mp[u][0][i] == INF) continue;
for(int j = 0; j < tot; ++j)
{
if(dis[u][j] == INF) continue;
int c = j|(1<<(i-1));
if(dis[i][c] > dis[u][j]+mp[u][0][j])
{
if(!vis[i])
{
vis[i] = 1;
q.push(i);
}
dis[i][c] = dis[u][j]+mp[u][0][i];
//printf("run:%d->%d dis:%d->%d vis:%d->%d\n",u,i,dis[u][j],dis[i][c],j,c);
}
for(int k = 0; k < n; ++k)
{
if((c&(1<<k)) == 0 || mp[u][k+1][i] == INF || dis[i][c] <= dis[u][j]+mp[u][k+1][i]) continue;
dis[i][c] = dis[u][j]+mp[u][k+1][i];
//printf("run:%d->%d dis:%d->%d vis:%d->%d\n",u,i,dis[u][j],dis[i][c],j,c);
//printf("%d->%d->%d\n",u,k+1,i);
if(!vis[i])
{
vis[i] = 1;
q.push(i);
}
}
}
}
}
}
int main()
{
//fread();
//fwrite();
int u,s,v,p,r;
while(~scanf("%d%d",&n,&m))
{
memset(mp,INF,sizeof(mp));
while(m--)
{
scanf("%d%d%d%d%d",&u,&v,&s,&p,&r);
mp[u][s][v] = min(mp[u][s][v],p);
mp[u][0][v] = min(mp[u][0][v],r);
}
tot = 1<<n;
spfa();
int mn = INF;
for(int i = 0; i < tot; ++i)
mn = min(mn,dis[n][i]);
if(mn == INF) puts("impossible");
else printf("%d\n",mn);
}
return 0;
}