POJ 2724 Purifying Machine
最小路径覆盖,但是涉及位运算。本来想用把串当做字符串处理,构图的时候再写个函数字符串匹配。。。想想也会超时。
查了解题报告,才知道用位运算 判断两个二进制数是不是只相差一位,
t=b[i]^b[j]; if(t&&(t&(t-1))==0)
代码:
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
#define MAX 2005
using namespace std;
int map[MAX][MAX],link[MAX],a[MAX],b[MAX];
int cnt;
bool vs[MAX];
bool dfs(int x)
{
int v;
for(int i=1;i<=map[x][0];i++)
{
v=map[x][i];
if(vs[v])continue;
vs[v]=1;
if(link[v]==-1||dfs(link[v]))
{
link[v]=x;
return 1;
}
}
return 0;
}
int MaxMacth()
{
int SUM=0;
memset(link,-1,sizeof(link));
for(int i=1;i<=cnt;i++)
{
memset(vs,0,sizeof(vs));
if(dfs(i))SUM++;
}
return SUM/2;
}
int main()
{
int N,M,i,j,k;
char ch[12];
while(~scanf("%d%d",&N,&M))
{
if(N==0&&M==0)break;
cnt=0;
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
while(M--)
{
scanf("%s",ch);
k=-1;
for(i=0;i<N;i++)
{
if(ch[i]=='*') k=i;
else a[cnt]|=((ch[i]-'0')<<i);//a[cnt]|=(1<<i);
}
if(k!=-1)
{
cnt++;
a[cnt]=(a[cnt-1]|(1<<k));
}
cnt++;
}
sort(a,a+cnt);
k=1;
b[1]=a[0];
for(i=1;i<cnt;i++)
{
if(b[k]==a[i])continue;
else
{
b[++k]=a[i];
}
}
cnt=k;
memset(map,0,sizeof(map));
int t,num;
for(i=1;i<=cnt;i++)
{
for(j=1;j<=cnt;j++)
{
t=b[i]^b[j];
if(t&&(t&(t-1))==0)
{
map[i][0]++;
map[i][map[i][0]]=j;
}
}
}
int ans=cnt-MaxMacth();
printf("%d\n",ans);
}
return 0;
}

浙公网安备 33010602011771号