标签:
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 1007 Accepted Submission(s): 353
题解:题意就是让找在这个矩阵中可以放的船最大数目;其中船之间可以有冰山,船间没冰山时船不能在同行同列;这样需要建图,先扫描行,如果遇到冰山t++;下一个数字可以继续匹配,下一行了t++,同样,再扫描列;得到二分匹配的x分部和y分部;
代码:
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #include<vector> using namespace std; const int INF=0x3f3f3f3f; const double PI=acos(-1.0); #define mem(x,y) memset(x,y,sizeof(x)) typedef long long LL; #define SI(x) scanf("%d",&x) #define SL(x) scanf("%lld",&x) #define T_T while(T--) #define F(i,x) for(i=0;i<x;i++) #define PR(x) printf("%d",x) #define PL(x) printf("%lld",x) #define p_ printf(" ") const int MAXN=1010; char s[MAXN][MAXN]; int mp[MAXN][MAXN],vis[MAXN],link[MAXN],x[110][110],y[110][110]; int m,n,t1,t2; int getmpxy(int rl,int a[][110]){//扫描行和列得到二分匹配的x部和y部 int t=0,i,j; if(rl)F(i,m){ F(j,n){ if(s[i][j]==‘*‘)a[i][j]=t; if(s[i][j]==‘#‘)t++; } t++; } else F(j,n){ F(i,m){ if(s[i][j]==‘*‘)a[i][j]=t; if(s[i][j]==‘#‘)t++; } t++; } return t; } void getmp(){ mem(x,0);mem(y,0); t1=getmpxy(1,x); t2=getmpxy(0,y); int i,j; F(i,m){ F(j,n){ if(s[i][j]==‘*‘){ // printf("%d %d\n",x[i][j],y[i][j]); mp[x[i][j]][y[i][j]]=1; } } } } bool dfs(int x){ int i,j; F(i,t2){ if(!vis[i]&&mp[x][i]){ vis[i]=1; if(link[i]==-1||dfs(link[i])){//|| link[i]=x; return true; } } } return false; } int km(){ mem(link,-1); int i,j; int ans=0; F(i,t1){ mem(vis,0); if(dfs(i))ans++; } return ans; } int main(){ int T; SI(T); T_T{ SI(m);SI(n); int i,j; mem(mp,0); F(i,m) scanf("%s",s[i]); getmp(); PR(km()); puts(""); } return 0; }
标签:
原文地址:http://www.cnblogs.com/handsomecui/p/4998906.html