NWERC2015 Elementary Math

来源:互联网 发布:找淘宝客服工作 编辑:程序博客网 时间:2024/06/16 20:48

#include<cstdio>#include<cstring>#include<algorithm>#define maxl 10010#define inf 2000000001using namespace std;int n,m,S=0,T=maxl-1,cnt=0,numcnt=0,ans;int ehead[maxl],q[maxl],dis[maxl],cur[maxl];long long a[maxl],b[maxl];struct calcnum{long long x;int ind,opt;} ha[maxl];struct ed{int w,nxt,to,opt;} e[maxl<<2];bool cmp(const calcnum &x,const calcnum &y){return x.x<y.x;}void add(int u,int v,int w,int opt){e[++cnt].to=v;e[cnt].nxt=ehead[u];e[cnt].w=w;e[cnt].opt=opt;ehead[u]=cnt;e[++cnt].to=u;e[cnt].nxt=ehead[v];e[cnt].w=0;e[cnt].opt=opt;ehead[v]=cnt;}//add写错就不谈了 ,cf上所有评测都要I64d,输入输出决不能一点差错 void prework(){scanf("%d",&n);int d;for(int i=1;i<=n;i++){scanf("%I64d%I64d",&a[i],&b[i]);d=(i-1)*3+1;ha[d].x=a[i]+b[i];ha[d].ind=i;ha[d].opt=1;d=(i-1)*3+2;ha[d].x=a[i]-b[i];ha[d].ind=i;ha[d].opt=2;d=(i-1)*3+3;ha[d].x=a[i]*b[i];ha[d].ind=i;ha[d].opt=3;add(S,i,1,0);}sort(ha+1,ha+1+3*n,cmp);numcnt++;add(ha[1].ind,n+numcnt,1,ha[1].opt);for(int i=2;i<=3*n;i++){if(ha[i].x!=ha[i-1].x)numcnt++;add(ha[i].ind,n+numcnt,1,ha[i].opt);}for(int i=1;i<=numcnt;i++)add(n+i,T,1,0);}int bfs(){int head=0,tail=1,u,i;memset(dis,-1,sizeof(dis));dis[S]=1;q[1]=S;while(head<tail){u=q[++head];for(i=ehead[u];i;i=e[i].nxt)if(e[i].w>0 && dis[e[i].to]<0){dis[e[i].to]=dis[u]+1;q[++tail]=e[i].to;}}if(dis[T]>0)return 1;elsereturn 0;}int min(int a,int b){if(a<b)return a;elsereturn b;}int find(int x,int low){int t;if(x==T)return low;for(int &i=cur[x];i;i=e[i].nxt)if(dis[e[i].to]==dis[x]+1 && e[i].w>0 && (t=find(e[i].to,min(e[i].w,low)))){e[i].w-=t;if(i&1)e[i+1].w+=t;elsee[i-1].w+=t;return t;}return 0;}void init(){cur[S]=ehead[S];cur[T]=ehead[T];for(int i=1;i<=n+numcnt;i++)cur[i]=ehead[i];}void mainwork(){int t=0;ans=0;while(bfs()){init();while(t=find(S,2000000001))ans+=t;}}void print(){int v;if(ans!=n)printf("impossible");else{for(int u=1;u<=n;u++)for(int i=ehead[u];i;i=e[i].nxt){v=e[i].to;if(v>n && v<=n+numcnt && e[i].w==0){if(e[i].opt==1)printf("%I64d + %I64d = %I64d\n",a[u],b[u],a[u]+b[u]);if(e[i].opt==2)printf("%I64d - %I64d = %I64d\n",a[u],b[u],a[u]-b[u]);if(e[i].opt==3)printf("%I64d * %I64d = %I64d\n",a[u],b[u],a[u]*b[u]);break;}}}}int main(){prework();mainwork();print();return 0;}

http://codeforces.com/gym/101485

2500对数,最多7500种结果,想到网络流,先预处理出所有不同的结果,然后全部连流量为1的边,数对到结果的边还要标记是+,-,*那种操作,跑完网络流,残余网络找一找每对数连出去的哪条边用完了。

此题add写错了,然后cf上交题一定要保证所有输入输出都符合变量原来的类型,而且是%I64d,不然WA on test 1。浪费好久时间- -。