题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=5889
最后10分钟被一群sb刷榜,杭电直接爆炸,导致这个题没交上,赛后30分钟杭电才判完题。之后交到题库直接AC。遗憾!
#include <cstdio>
#include <cstring>
#include <cmath>
#include <ctime>
#include <cstdlib>
#include <queue>
#include <stack>
#include <string>
#include <map>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long LL;
#define tap(x) for(Edge *p=aa[x]; p; p=p->p)
#define Cls(a) memset((a), 0, sizeof(a))
#define mem(a, x) memset((a), (x), sizeof(a))
const int inf = 0x3f3f3f3f;
typedef struct Edge
{
Edge *p, *q;
int to, cc;
} Edge;
Edge edge[250010];
Edge *aa[1002],*cur[1002],*pt;
int n,m,ans=0,a[100002],b[100002],c[100002],t[100002],d[2][1002];
bool isin[1002];
queue <int> q;
inline bool scan_d(int &num)
{
char in;
bool IsN=false;
in=getchar();
if(in==EOF) return false;
while(in!='-'&&(in<'0'||in>'9')) in=getchar();
if(in=='-')
{
IsN=true;
num=0;
}
else num=in-'0';
while(in=getchar(),in>='0'&&in<='9')
{
num*=10,num+=in-'0';
}
if(IsN) num=-num;
return true;
}
inline void addedge(int x,int y,LL z)
{
pt->p = aa[x];
pt->to = y;
pt->cc = z;
aa[x] = pt++;
}
inline void add(int x,int y,LL z)
{
addedge(x,y,z);
addedge(y,x,0);
aa[x]->q = aa[y];
aa[y]->q = aa[x];
}
void spfa(int x,int t)
{
mem(d[t],inf);
d[t][x] = 0;
mem(isin,0);
isin[x] = 1;
q.push(x);
while (!q.empty())
{
int nn = q.front();
q.pop();
isin[nn] = 0;
tap(nn)
{
if (d[t][p->to] > d[t][nn] + p->cc)
{
d[t][p->to] = d[t][nn] + p->cc;
if (!isin[p->to])
{
isin[p->to] = 1;
q.push(p->to);
}
}
}
}
}
bool bfs()
{
while (!q.empty()) q.pop();
mem(d[0],-1);
d[0][1] = 0;
q.push(1);
while (!q.empty())
{
int nn = q.front();
q.pop();
tap(nn)
{
if (d[0][p->to] == -1 && p->cc > 0)
{
d[0][p->to] = d[0][nn] + 1;
q.push(p->to);
if (p->to == n) return 1;
}
}
}
return 0;
}
int dfs(int x,int flow)
{
if (x == n || (!flow)) return flow;
int w = 0;
for(Edge *p=cur[x]; p && w < flow; p=p->p)
{
if (d[0][p->to] == d[0][x] + 1 && p->cc > 0)
{
int xx = dfs(p->to,min(p->cc,flow-w));
p->cc -= xx;
p->q->cc += xx;
w += xx;
if (p->cc) cur[x] = p;
}
}
if (w < flow) d[0][x] = -1;
return w;
}
int main()
{
int T;
scan_d(T);
while(T--)
{
scan_d(n);
scan_d(m);
mem(aa,0);
pt = edge;
for(int i=1; i<m+1; i++)
{
scan_d(a[i]);
scan_d(b[i]);
t[i] = 1;
scan_d(c[i]);
addedge(a[i],b[i],t[i]);
addedge(b[i],a[i],t[i]);
}
spfa(1,0);
spfa(n,1);
mem(aa,0);
pt = edge;
ans = 0;
for(int i=1; i<m+1; i++)
{
if (d[0][a[i]] + t[i] + d[1][b[i]] == d[0][n])
{
add(a[i],b[i],c[i]);
}
if (d[0][b[i]] + t[i] + d[1][a[i]] == d[0][n])
{
add(b[i],a[i],c[i]);
}
}
while (bfs())
{
for(int i=1; i<n+1; i++)
{
cur[i] = aa[i];
}
ans += dfs(1, inf);
}
printf("%d\n",ans);
}
return 0;
}