sgu-212 Data Transmission

来源:互联网 发布:我的世界进服务器java 编辑:程序博客网 时间:2024/04/29 11:00

 题目大意:

给你一个图,n(点数),m(边数),l,和每个点上的标号h,h表示到源点的最短路,h=1表示是源点,h=l表示是汇点,显然是一个层次图,然后要你求最大流。


解题思路:

首先我们注意一下数据范围,然后我就怂了,本来看到题目觉得就是分分钟dinic上去秒掉的,但是我还是too naive,所以我只能滚粗去学预流推进了。。。。。。。

由于预流推进很难讲,所以请大家自己去查阅资料吧。

我们假设大家都会了预流推进,但是我自己写的最高标号预流推进居然超时了,然后我就各种丧心病狂的优化,我来介绍一点优化吧!

优化1:输出优化,把所有要输出的都转成字符串,然后用putchar或者puts

优化2:我们不需要进行BFS或着DFS,只需要用输入的h就行了

优化3:听说sgu开了O2对吧,inline函数搞起!!

优化4:我们应该尽量开小空间,因为空间小速度快啊!!!

优化5:用hash表示这个数是否在优先队列中,以免重复进队!!


AC代码:

#include <cstdio>#include <cstdlib>#include <cstring>#include <cmath>#include <iostream>#include <algorithm>#include <queue>#define MAX(a,b) ((a)>(b)?(a):(b))#define MIN(a,b) ((a)>(b)?(b):(a))using namespace std;short h[1510]={0};struct list{int x;int H;bool friend operator < (const list &a,const list &b){return a.H<b.H;}};struct bian_{short num;int next;}b[600010]={{0,0}};int First[1510]={0};int n,m,l;int s,t;priority_queue <list> dui;int flow[1510][1510]={{0}};int yl[1510]={0};short bian[300010][2]={{0}};int ss=0;bool hash[1510]={0};char ans[100000]="\0";int ansp;inline void Add(int i,int j,int k){b[k].num=j;b[k].next=First[i];First[i]=k;return;}inline void get_ch(int k){char help[10]="\0";int i;if(k==0)ans[++ansp]='0';else{for(i=0;k!=0;k/=10)help[++i]=k%10+'0';for(;i>0;--i)ans[++ansp]=help[i];}ans[++ansp]='\n';return;}int main(){scanf("%d%d%d",&n,&m,&l);for(register int i=1;i<=n;++i){scanf("%d",&h[i]);if(h[i]==1)s=i;if(h[i]==l)t=i;h[i]=l+1-h[i];}for(register int i=1;i<=m;++i){scanf("%d%d",&bian[i][0],&bian[i][1]);scanf("%d",&flow[bian[i][0]][bian[i][1]]);Add(bian[i][0],bian[i][1],i*2-1);Add(bian[i][1],bian[i][0],i*2);}h[s]=l+1;yl[s]=2e9;yl[t]=-2e9;struct list q;q.x=s;q.H=h[s];dui.push(q);hash[s]=1;++ss;for(;ss!=0;){q=dui.top();dui.pop();--ss;int u=q.x;hash[u]=0;for(register int i=First[u];i!=0;i=b[i].next){int v=b[i].num;if(yl[u]==0) break;int p=MIN(flow[u][v],yl[u]);if(p>0 && (u==s || h[u]==h[v]+1)){flow[u][v]-=p;flow[v][u]+=p;yl[u]-=p;yl[v]+=p;if(v!=s && v!=t && hash[v]==0){q.x=v;q.H=h[v];dui.push(q);++ss;hash[v]=1;}}}if(u!=s && u!=t && yl[u]>0){++h[u];q.x=u;q.H=h[u];dui.push(q);++ss;hash[u]=1;}}for(register int i=1;i<=m;++i)get_ch(flow[bian[i][1]][bian[i][0]]);for(register int i=1;i<=ansp;++i)putchar(ans[i]);return 0;}


0 0
原创粉丝点击