#include<cstdio>
#include<cstring>
#include<algorithm>
#define maxl 10010
#define inf 2000000001
using 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;
else
return 0;
}
int min(int a,int b)
{
if(a<b)
return a;
else
return 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;
else
e[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。浪费好久时间- -。