题意分析:把一对数字看成一个点A,然后把一对数字的和、差、积视作另外三个点,把点A与这三个点连接起来可构成
一个二分图,然后跑匈牙利求最大匹配就好了。
图论果然难在建图与模型搭建啊,题目做得还是少了,WA了几次是因为相乘时没加(LL),这个错误犯了好几次了,
这次必须记下来!!
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<map>
using namespace std;
typedef long long LL;
int ax[2510],bx[2510];
LL Map[2510][5];
map<LL,int> pre;
map<LL,bool> ac;
int N;
char cx[3]={'-','+','*'};
bool dfs(int x)
{
for(int i=0;i<3;i++)
{
LL z=Map[x][i];
if(!ac[z])
{
ac[z]=1;
if(pre[z]==0||dfs(pre[z]))
{
pre[z]=x;
return true;
}
}
}
return false;
}
bool find1()
{
int cnt=0;
pre.clear();
for(int i=1;i<=N;i++)
{
ac.clear();
if(dfs(i))
cnt++;
}
return cnt==N;
}
int main()
{
while(scanf("%d",&N)!=EOF)
{
memset(Map,0,sizeof(Map));
for(int i=1;i<=N;i++)
{
int a,b;
scanf("%d%d",&a,&b);
Map[i][0]=a-b,Map[i][1]=a+b,Map[i][2]=(LL)a*b;
ax[i]=a,bx[i]=b;
}
if(find1())
{
for(int i=1;i<=N;i++)
{
for(int j=0;j<3;j++)
{
if(pre[Map[i][j]]==i)
{
printf("%d %c %d = %lld\n",ax[i],cx[j],bx[i],Map[i][j]);
break;
}
}
}
}
else
{
printf("impossible\n");
}
}
return 0;
}