CQOI2015送分題。(馬上省選了好緊張好緊張好緊張好緊張)
題目上已經把怎麼做說得一清二楚了。先跑最短路,只有屬於某條最短路的邊是可以走的;把它們拿出來,拆點網絡流即可。
(我這麼弱只有切這種水題了,竟然還切了一下午…… 我真是沒救了麼……)
(不要隨便看代碼,不要隨便看代碼,不要隨便看代碼。因爲很重要說以說三遍)
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <queue>
using namespace std;
//Global Variables & Definitions
#define LL long long
#define MAXN 550
#define MAXM 100010
#define INF 0x3fffffff
#define REV(i) ((i) ^ 1)
#define IN(x) (x)
#define OUT(x) ((x) + 510)
#define MS(arr, x) memset(arr, x, sizeof(arr))
#define S OUT(1)
#define T IN(N)
int N, M;
void init_edge2(void);
void adde2(int, int, int);
//End Global Variables & Definitions
//Map
struct edge {
int u, v, w, next;
} e[MAXM * 2];
int ecnt;
int h[MAXN * 2];
inline void init_edge() {
memset(h, ecnt = -1, sizeof(h));
}
void adde(int u, int v, int w) {
++ecnt;
e[ecnt].u = u;
e[ecnt].v = v;
e[ecnt].w = w;
e[ecnt].next = h[u];
h[u] = ecnt;
}
queue<int> q;
int dis[MAXN * 2];
int inq[MAXN * 2];
void SPFA() {
MS(dis, 0x3f);
MS(inq, 0);
dis[1] = 0; inq[1] = 1; q.push(1);
while(!q.empty()) {
int temp = q.front(); q.pop();
inq[temp] = 0;
int v;
for(int i = h[temp];~i;i = e[i].next) if(dis[v = e[i].v] > dis[temp] + e[i].w) {
dis[v] = dis[temp] + e[i].w;
if(!inq[v]) {
inq[v] = 1;
q.push(v);
}
}
}
init_edge2();
for(int i = 0;i <= ecnt;++i) if(dis[e[i].u] + e[i].w == dis[e[i].v]) {
adde2(OUT(e[i].u), IN(e[i].v), INF);
}
int temp;
for(int i = 1;i <= N;++i) {
scanf("%d", &temp);
adde2(IN(i), OUT(i), temp);
}
}
#undef edge
struct edge_ {
int v, next;
int cap, flow;
} e2[MAXM * 4];
int ecnt2;
int h2[MAXN * 2];
void init_edge2() {
memset(h2, ecnt2 = -1, sizeof(h2));
}
void _adde2(int u, int v, int cap) {
++ecnt2;
e2[ecnt2].v = v;
e2[ecnt2].cap = cap;
e2[ecnt2].flow = 0;
e2[ecnt2].next = h2[u];
h2[u] = ecnt2;
}
void adde2(int u, int v, int cap) {
_adde2(u, v, cap);
_adde2(v, u, 0);
}
#undef e
#undef h
#undef ecnt
#define e e2
#define h h2
#define ecnt ecnt2
bool BFS() {
MS(dis, 0xff);
dis[S] = 0; q.push(S);
while(!q.empty()) {
int temp = q.front(); q.pop();
int v;
for(int i = h[temp];~i;i = e[i].next) if(e[i].cap > e[i].flow) {
if(~dis[v = e[i].v]) continue;
dis[v] = dis[temp] + 1;
q.push(v);
}
}
return ~dis[T];
}
LL dfs(int u, int a) {
if(u == T || a == 0) return a;
LL tflow, totflow = 0;
for(int i = h[u];~i;i = e[i].next) if(dis[e[i].v] == dis[u] + 1 && e[i].cap > e[i].flow) {
tflow = dfs(e[i].v, min(a, e[i].cap - e[i].flow));
e[i].flow += tflow;
e[REV(i)].flow -= tflow;
totflow += tflow;
a -= tflow;
if(!a) break;
}
return totflow;
}
LL Dinic() {
LL ans = 0;
while(BFS()) ans += dfs(OUT(1), INF);
return ans;
}
//End Map
//Main Structure
inline void ir() {
init_edge();
freopen("network.in", "r", stdin);
freopen("network.out", "w", stdout);
scanf("%d%d", &N, &M);
int aa, bb, dd;
for(int i = 0;i < M;++i) {
scanf("%d%d%d", &aa, &bb, &dd);
adde(aa, bb, dd);
adde(bb, aa, dd);
}
}
int main() {
ir();
SPFA();
printf("%I64d\n", Dinic());
return 0;
}