裸最大流,不过,可能是hdu的爆栈问题?或者是模板效率问题?貌似卡了不少同学,要不不应该这么惨的吧……
当时dinic递归版交上发现是RE(stack over flow),于是LC果断认定是递归的问题,换了个非递归的dinic,7000ms+过掉。赛后pictureyong说 HDU 的栈本身就有问题,加个外挂试试(http://blog.csdn.net/hqd_acm/article/details/6648290),果断的,递归版dinic加外挂,也能A,不过跑了9500ms+……
dinic 递归+挂,9000ms+
#include<cstdio> #include<cstring> #include<queue> #include<cmath> //就是这句了,真心亮啊!!! #pragma comment(linker, "/STACK:1024000000,1024000000") #define find_min(a,b) a<b?a:b using namespace std; const int N = 100010; const int MAX = 10000000; struct Edge{ int s,e,next; int v; }edge[2*N]; int n,e_num,head[N],d[N],sp,tp; void AddEdge(int a,int b,int c){ edge[e_num].s=a; edge[e_num].e=b; edge[e_num].v=c; edge[e_num].next=head[a]; head[a]=e_num++; edge[e_num].s=b; edge[e_num].e=a; edge[e_num].v=c; edge[e_num].next=head[b]; head[b]=e_num++; } int bfs(){ queue <int> q; memset(d,-1,sizeof(d)); d[sp]=0; q.push(sp); while(!q.empty()){ int cur=q.front(); q.pop(); for(int i=head[cur];i!=-1;i=edge[i].next){ int u=edge[i].e; if(d[u]==-1 && edge[i].v>0){//没有标记,且可行流大于0 d[u]=d[cur]+1; q.push(u); } } } return d[tp] != -1;//汇点是否成功标号,也就是说是否找到增广路 } int dfs(int a,int b){//a为起点 double r=0; if(a==tp)return b; for(int i=head[a];i!=-1 && r<b;i=edge[i].next){ int u=edge[i].e; if(edge[i].v>0 && d[u]==d[a]+1){ double x=find_min(edge[i].v,b-r); x=dfs(u,x); r+=x; edge[i].v-=x; edge[i^1].v+=x; } } if(!r)d[a]=-2; return r; } int dinic(int sp,int tp){ int total=0,t; while(bfs()){ while(t=dfs(sp,MAX)) total+=t; } return total; } int main() { int t,i,n,m,a,b,c; int x,y; scanf("%d",&t); while(t--) { scanf("%d%d",&n,&m); int min_x=MAX,max_x=-MAX; int min_id=1,max_id=1; for(i=1;i<=n;i++){ scanf("%d%d",&x,&y); if(x<min_x){ min_x = x; min_id = i; } if(x>max_x){ max_x = x; max_id = i; } } sp=min_id; tp=max_id; e_num=0; memset(head,-1,sizeof(head)); for(i=1;i<=m;i++){ scanf("%d%d%d",&a,&b,&c); AddEdge(a,b,c); } int ans=dinic(sp,tp); printf("%d\n",ans); } return 0; }
这个是LC的dinic非递归版,7000ms+,不用开挂也能过:
#include<stdio.h> #include<string.h> #include<stdlib.h> #define NODE_SIZE 100010 #define EDGE_SIZE 400010 #define INF 0x7fffff struct info{ int s,e,f,next; }edge[EDGE_SIZE]; int edge_num; int head[NODE_SIZE]; int Que[NODE_SIZE]; int level[NODE_SIZE]; int cur_head[NODE_SIZE]; int edge_stack[4 * NODE_SIZE + 4 * EDGE_SIZE]; int stack_top; int source,sink; void add_edge(int s,int e,int f) { int t = edge_num; edge[t].s = s; edge[t].e = e; edge[t].f = f; edge[t].next = head[s]; head[s] = edge_num ++; } int BFS() { int fr,tp,cur,next,e; memset(level,-1,sizeof(level)); Que[0] = source; level[source] = 0; for( fr = 0,tp = 1; fr != tp; fr = (fr + 1)%NODE_SIZE ){ cur = Que[fr]; for( e = head[cur]; e != -1; e = edge[e].next ){ next = edge[e].e; if( edge[e].f && level[next] == -1 ){ Que[tp] = next; level[next] = level[cur] + 1; tp = (tp + 1)%NODE_SIZE; } } } return level[sink] != -1; } int find_max_flow() { int cur,e,next; int i,index,min_limit; int res = 0; memcpy(cur_head,head,sizeof(head)); cur = source; stack_top = 0; while( stack_top >= 0 ){ if( cur == sink ){ min_limit = INF; for( i = stack_top - 1; i >= 0 ; i -- ){ e = edge_stack[i]; if( edge[e].f <= min_limit ){ min_limit = edge[e].f; index = i; } } res += min_limit; for( i = stack_top - 1; i >= 0; i -- ){ e = edge_stack[i]; edge[e].f -= min_limit; edge[e ^ 1].f += min_limit; } stack_top = index; cur = edge[ edge_stack[ stack_top ] ].s; } for( e = cur_head[cur]; e != -1; e = edge[e].next ){ cur_head[cur] = e; next = edge[e].e; if( edge[e].f && level[next] == level[cur] + 1 ){ edge_stack[stack_top ++] = e; cur = next; break; } } if( e == -1 ){ stack_top --; level[cur] = -2; cur = edge[ edge_stack[stack_top] ].s; } } return res; } int main() { int t,i,n,m,a,b,c; int x,y; int res; scanf("%d",&t); while(t--) { scanf("%d%d",&n,&m); int min_x=INF,max_x=-INF; int min_id=1,max_id=1; for(i=1;i<=n;i++){ scanf("%d%d",&x,&y); if(x<min_x){ min_x = x; min_id = i; } if(x>max_x){ max_x = x; max_id = i; } } source=min_id; sink=max_id; edge_num=0; memset(head,-1,sizeof(head)); for(i=1;i<=m;i++){ scanf("%d%d%d",&a,&b,&c); add_edge(a,b,c); add_edge(b,a,c); } res = 0; while( BFS() ){ res += find_max_flow(); } printf("%d\n",res); } return 0; }