# 牛客多校第五场 A Portal 图 dp

## Portal

### 题解

a1，b1，a2，b2，a3，b3设为ci。

dp[i][j]表示当前走了i个点（在ci点处），传送门在j。

#include<algorithm>
#include<cstring>
#include <iostream>
#include <cstdio>
#include <queue>
#include <map>
#include <set>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
typedef pair<double,double> pdd;
typedef unsigned long long ull;
typedef set<int>::iterator sit;
#define st first
#define sd second
#define mkp make_pair
#define pb push_back
void tempwj(){freopen("hash.in","r",stdin);freopen("hash.out","w",stdout);}
ll gcd(ll a,ll b){return b == 0 ? a : gcd(b,a % b);}
ll qpow(ll a,ll b,ll mod){a %= mod;ll ans = 1;while(b){if(b & 1)ans = ans * a % mod;a = a * a % mod;b >>= 1;}return ans;}
struct cmp{bool operator()(const pii & a, const pii & b){return a.second < b.second;}};
int lb(int x){return  x & -x;}
//friend bool operator < (Node a,Node b)   重载
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f;
const ll mod = 1e9 + 7;
const int maxn = 305+10;
ll dp[605][maxn];
//dp[i][j]表示：目前完成了i个任务，一个传送门在j点
ll dis[maxn << 1][maxn];
int a[maxn << 1];
int main()
{
int n,m,k;
scanf("%d%d%d",&n,&m,&k);
for (int  i= 1; i <= n; i ++ )
{
for (int j = 1; j <= n; j ++ )
dis[i][j] = INF;
dis[i][i] = 0;
}
for(int i = 1; i <= m; i ++ )
{
int x,y;
ll v;
scanf("%d%d%lld",&x,&y,&v);
dis[x][y] = dis[y][x] = min(dis[x][y], v);
}
for (int k = 1; k <= n; k ++ )
{
for(int i = 1; i <= n; i ++ )
{
for(int j = 1; j <= n; j ++ )
{
if(dis[i][j] > dis[i][k] + dis[k][j])
dis[i][j] = dis[i][k] + dis[k][j];
}
}
}
for (int i = 1; i <= 2 * k; i ++ )
{
scanf("%d",&a[i]);
}
a[0] = 1;
for(int i = 0; i <= 2 * k; i ++ )
{
for(int j = 0; j <= n; j ++ )
dp[i][j] = INF;
}
dp[0][1] = 0;
for(int i = 0; i < 2 * k; i ++ )
{
for (int j = 1; j <= n; j ++ )
{
if(dp[i][j] == INF)
continue;
dp[i + 1][j] = min(dp[i + 1][j], dp[i][j] + dis[a[i]][a[i + 1]]);// 位置没有变化
for(int kk = 1; kk <= n; kk ++ )
{
dp[i + 1][kk] = min(dp[i][j] + dis[a[i]][kk] + dis[kk][a[i + 1]], dp[i + 1][kk]);
dp[i + 1][kk] = min(dp[i][j] + dis[a[i]][kk] + dis[j][a[i + 1]], dp[i + 1][kk]);//从k传送到j
dp[i + 1][kk] = min(dp[i][j] + dis[j][kk] + dis[kk][a[i + 1]], dp[i + 1][kk]);
}
}
}
ll ans = INF;
for (int i = 1; i <= n; i ++ )
{
ans = min(ans,dp[2 * k][i]);
}
printf("%lld\n", ans);
}


07-26 189