poj3686 km算法 巧妙的构图

来源:互联网 发布:c语言音乐播放器 编辑:程序博客网 时间:2024/06/05 08:18

看的shy的写的,实在是不会建图啊。。。

早晨开始写的中午还挑了一会儿,下午唱完合唱才闹对。。。

程序书写易错点:用if判断两个条件的时候要分别加上括号!!!

#include<iostream>#include<algorithm>#include<cstring>#include<cstdio>#define inf 9000000using namespace std;int vis_x[60],vis_y[2600],l[60],r[2600],slack[2600];int dd[60][2600];int n,m,father[2600],map[60][2600],d;bool dfs(int x){vis_x[x]=1;for(int j=1;j<=n*m;j++)if(!vis_y[j]&&l[x]+r[j]==map[x][j]){vis_y[j]=1;if((!father[j])||dfs(father[j])){father[j]=x;return 1;}}elseif(l[x]+r[j]>map[x][j] && !vis_y[j])slack[j]=min(slack[j],l[x]+r[j]-map[x][j]);return 0;}void km(){for(int i=1;i<=n;i++){int flag=0;//system("pause");while(!flag){memset(vis_x,0,sizeof(vis_x));memset(vis_y,0,sizeof(vis_y));memset(slack,63,sizeof(slack));if(dfs(i))flag=1;if(!flag){d=inf;for(int j=1;j<=m*n;j++)if(!vis_y[j]&&d>slack[j])d=slack[j];for(int j=1;j<=n;j++)if(vis_x[j])l[j]-=d;for(int j=1;j<=n*m;j++)if(vis_y[j])r[j]+=d;}}}}void debug(){for(int i=1;i<=n;i++){for(int j=1;j<=n*m;j++)printf("%d ",map[i][j]);printf("\n");}return ;}int main(){int u;scanf("%d",&u);for(int xu=1;xu<=u;xu++){getchar();scanf("%d%d",&n,&m);for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)scanf("%d",&dd[i][j]);memset(l,0,sizeof(l));memset(r,0,sizeof(r));for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)for(int k=1;k<=n;k++){map[i][j*n-n+k]=inf-k*dd[i][j];l[i]=max(l[i],map[i][j*n-n+k]);}memset(father,0,sizeof(father));km();double ans=0;for(int j=1;j<=n*m;j++)if(father[j])ans+=inf-map[father[j]][j];ans/=n;printf("%.6f\n",ans);}return 0;}

0 0