/*
* @Author: Achan
* @Date: 2018-10-29 19:10:05
* @Last Modified by: Achan
* @Last Modified time: 2018-10-29 21:57:25
*/
#include<bits/stdc++.h>
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cstdlib>
#include<iomanip>
#include<vector>
#include<queue>
#include<cmath>
using namespace std;
#define X first
#define Y second
#define eps 1e-2
#define gcd __gcd
#define pb push_back
#define PI acos(-1.0)
#define lowbit(x) (x)&(-x)
#define fin freopen("in.txt","r",stdin);
#define fout freopen("out.txt","w",stdout);
#define bug printf("!!!!!\n");
#define mem(x,y) memset(x,y,sizeof(x))
#define rep(i,j,k) for(int i=j;i<(int)k;i++)
#define per(i,j,k) for(int i=j;i<=(int)k;i++)
#define pset(x) setiosflags(ios::fixed)<<setprecision(x)
#define io std::ios::sync_with_stdio(false),cin.tie(NULL),cout.tie(NULL);
typedef long long ll;
typedef long double LD;
typedef pair<int,int> pii;
typedef unsigned long long ull;
const int inf = 1<<30;
const ll INF = 1e18 ;
const int mod = 1e9+7;
const int maxn = 4e2+2;
const int mov[4][2] = {-1,0,1,0,0,1,0,-1};
const int Mov[8][2] = {-1,-1,-1,0,-1,1,0,-1,0,1,1,-1,1,0,1,1};
inline int read(){
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
int tot;
int n,m;
int head[maxn];
struct edge
{
int w;
int to;
int nex;
}E[maxn*maxn +maxn];
inline void init(){tot = 0; memset(head,-1,sizeof(head)); }
inline void add_edge(int u, int v, int w)
{
E[tot].to = v;
E[tot].w = w;
E[tot].nex = head[u];
head[u] = tot++;
}
int dis[maxn];
int vis[maxn];
void Dijktra(int s)
{
memset(vis,0,sizeof(vis));
fill(dis,dis+n+m+1,inf);
dis[s] = 0;
priority_queue <pair<int , int> > q;
q.push(make_pair(0,s));
while(!q.empty())
{
int cur = q.top().second;
q.pop();
if(vis[cur]) continue;
vis[cur] = 1;
for(int i = head[cur]; ~i; i = E[i].nex)
{
int w = E[i].w;
int to = E[i].to;
if(!vis[to] && dis[to] > dis[cur] + w) //vis[to] 不要习惯写成vis[i]
{
dis[to] = dis[cur] + w;
q.push(make_pair(-dis[to] , to));
}
}
}
}
int ex_b[maxn],ex_g[maxn];
bool visb[maxn],visg[maxn];
int match[maxn],slack[maxn];
int mp[maxn][maxn];
bool DFS(int cur)
{
visg[cur] = 1;
for(int i = 1; i<= n;i++)
{
if(visb[i]) continue;
int gap = ex_b[i] + ex_g[cur] - mp[cur][i];
if(!gap)
{
visb[i] = 1;
if(match[i]==-1 || DFS(match[i]))
{
match[i] = cur;
return true;
}
}
else slack[i] = min(slack[i],gap);
}
return false;
}
void KM()
{
memset(ex_b,0,sizeof(ex_b));
memset(match,-1,sizeof(match));
for(int i = 1; i<=n ; i++)
{
fill(slack,slack + n + 1,inf);
while(1)
{
memset(visb,0,sizeof(visb));
memset(visg,0,sizeof(visg));
if(DFS(i)) break;
int d = inf;
for(int j = 1; j<=n ; j++) if(!visb[j]) d = min(d,slack[j]);
for(int j = 1; j<=n ; j++)
{
if(visg[j]) ex_g[j] -= d;
if(visb[j]) ex_b[j] += d;
else slack[j] -= d;
}
}
}
int ans = 0;
for(int i = 1; i<=n ;i++) ans += mp[match[i]][i];
printf("%lld\n",-ans);
}
int op[maxn];
int main(void)
{
int k,p;
while(~scanf("%d%d%d%d",&n,&m,&k,&p))
{
init();
for(int i=1;i<=n;i++) op[i] = read();
for(int i=1;i<=k;i++)
{
int u,v,w;
u = read(), v = read(), w = read();
add_edge(u,v,w);
add_edge(v,u,w);
}
for(int i=1;i<=p;i++)
{
int u,v,w;
u = read(), v = read(), w = read();
add_edge(v,u+m,w); //矿与港口建单边
}
//建立 n*n二分图
for(int i=1;i<=n;i++) //n个船
{
Dijktra(op[i]); int maxg = -inf;
for(int j = m+1; j<= m+n ; j++) //遍历n个港口
mp[i][j-m] = -dis[j] , maxg = max(maxg, -dis[j]);
ex_g[i] = maxg;
}
KM();
}
}
Accepted time:452MS memory:2328K length:4068 B
Mining Station on the Sea (Dijktra + KM)
最新推荐文章于 2019-08-06 17:39:03 发布