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; }