POJ2686--Travelling by Stagecoach

2034 단어
제목의 뜻: m개 도시, p개 양방향 도로, n장의 차표, 위에 말의 수량이 기록되어 있다. 한 도시에서 다른 도시까지 모두 차표를 써야 한다. 시간은 두 도시 사이의 도로의 길이를 차표로 나누어 말에 오르는 수량이다.도시 a에서 도시 b까지의 가장 짧은 시간을 구합니다. 출력 Impossible에 도달할 수 없습니다
분석:상압DP.상태: dp[S][v], 도시 v에 도착하고 남은 차표의 집합이 S일 때의 가장 짧은 시간
상태 전이 방정식: dp[S&~(1<코드:
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

const int maxn = 1111;
double dp[maxn][35];
int g[35][35];
int t[10];
int n, m, p, a, b;

int main() {
    while(scanf("%d%d%d%d%d", &n, &m, &p, &a, &b) && n != 0 && m != 0) {
        for(int i = 0; i < n; i++)
            scanf("%d", &t[i]);
        for(int i = 0; i < m; i++)
            memset(g[i], -1, sizeof(g[i]));
        for(int i = 0; i < p; i++) {
            int u, v, w;
            scanf("%d%d%d", &u, &v, &w);
            u--, v--;
            g[u][v] = w;
            g[v][u] = w;
        }
        for(int i = 0; i < 1<<n; i++)
            fill(dp[i], dp[i]+m, 100000000.0);
        dp[(1<<n)-1][a-1] = 0.0;
        double ans = 100000000.0;
        for(int S = (1<<n) -1; S >= 0; S--) {
            ans = min(ans, dp[S][b-1]);
            for(int v = 0; v < m; v++) {
                for(int i = 0; i < n; i++) {
                    if(S>>i & 1) {
                        for(int u = 0; u < m; u++) {
                            if(g[v][u] >= 0) {
                                //    i,   v   u
                                dp[S & ~(1<<i)][u] = min(dp[S & ~(1<<i)][u], dp[S][v] + g[v][u]*1.0/t[i]);
                            }
                        }
                    }
                }
            }
        }
        if(ans != 100000000.0) printf("%.3f
", ans); else printf("Impossible
"); } return 0; }

좋은 웹페이지 즐겨찾기