【最短路】 HDOJ 3870 Catch the Theves

来源:互联网 发布:通达信macd公式源码 编辑:程序博客网 时间:2024/05/22 11:36

详细解法参考论文————两极相通——浅析最大—最小定理在信息学竞赛中的应用

论文已经讲的很详细了。。。建图跑最短路就可以了。。。

#include <iostream>#include <queue> #include <stack> #include <map> #include <set> #include <bitset> #include <cstdio> #include <algorithm> #include <cstring> #include <climits>#include <cstdlib>#include <cmath>#include <time.h>#define maxn 200005#define maxm 20000005#define eps 1e-10#define mod 1000000007#define INF 0x3f3f3f3f#define lowbit(x) (x&(-x))#define mp make_pair#define ls o<<1#define rs o<<1 | 1#define lson o<<1, L, mid #define rson o<<1 | 1, mid+1, R typedef long long LL;typedef unsigned long long ULL;//typedef int LL;using namespace std;struct Edge{int v, c;Edge *next;}pool[maxm], *H[maxn], *edges;struct node{int u, d;node(int u = 0, int d = 0) : u(u), d(d) {}bool operator < (const node& b) const {return d > b.d;}};priority_queue<node> q;int dist[maxn], vis[maxn];int g[405][405];int n;void addedges(int u, int v, int c){edges->v = v;edges->c = c;edges->next = H[u];H[u] = edges++;}void init(void){edges = pool;memset(H, 0, sizeof H);memset(vis, 0, sizeof vis);memset(dist, 0x3f, sizeof dist);}inline int calc(int i, int j){return (i - 1) * (n - 1) + j;}void read(void){scanf("%d", &n);for(int i = 1; i <= n; i++)for(int j = 1; j <= n; j++)scanf("%d", &g[i][j]);}int dijstra(int s, int t){dist[s] = 0;q.push(node(s, dist[s]));while(!q.empty()) {int u = q.top().u, d = q.top().d;q.pop();if(vis[u]) continue;vis[u] = 1;for(Edge *e = H[u]; e; e = e->next) {if(dist[e->v] > dist[u] + e->c) {dist[e->v] = dist[u] + e->c;q.push(node(e->v, dist[e->v]));}}}return dist[t];}void debug(void){for(int i = 0; i <= n * n + 1; i++) {printf("AA %d ::\n", i);for(Edge *e = H[i]; e; e = e->next) {printf("v = %d c = %d\n", e->v, e->c);}}}void work(void){int s = 0, t = n * n + 1;for(int i = 1; i < n; i++) {for(int j = 1; j < n; j++) {if(i != n-1) {addedges(calc(i, j), calc(i+1, j), g[i+1][j]);addedges(calc(i+1, j), calc(i, j), g[i+1][j]);}if(j != n-1) {addedges(calc(i, j), calc(i, j+1), g[i][j+1]);addedges(calc(i, j+1), calc(i, j), g[i][j+1]);}}}for(int i = 1; i < n; i++) {addedges(calc(1, i), t, g[1][i]);addedges(t, calc(1, i), g[1][i]);}for(int i = 1; i < n; i++) {addedges(calc(i, n-1), t, g[i][n]);addedges(t, calc(i, n-1), g[i][n]);}for(int i = 1; i < n; i++) {addedges(calc(i, 1), s, g[i][1]);addedges(s, calc(i, 1), g[i][1]);}for(int i = 1; i < n; i++) {addedges(calc(n-1, i), s, g[n][i]);addedges(s, calc(n-1, i), g[n][i]);}printf("%d\n", dijstra(s, t));}int main(void){int _;while(scanf("%d", &_)!=EOF) {while(_--) {init();read();work();}}return 0;}


0 0