您的位置:首页 > 其它

POJ3216 floyd+二分图应用(最小路径覆盖)

2011-08-26 22:25 633 查看
主要难点是在最小路径覆盖,详细见本博客转载的 最小路径覆盖。

不得不是说,这是一道很不错的题目。

刚开始wa。是因为没理解清楚最小路径覆盖的二分图思想。

构图的时候要注意,每个节点代表任务,而不是block。

当这个任务i做完可以去做任务j。则match[i][j]=true.

这个很关键。

#include<iostream>

using namespace std;

int q,m;

const int Q=22,M=202;

int mat[Q][Q];

struct

{

int p,t,d;

}task[M];

int link[M];

bool visit[M];

bool match[M][M];

const int inf=99999999;

void floyd()

{

for(int k=1;k<=q;k++)

for(int i=1;i<=q;i++)

for(int j=1;j<=q;j++)

{

if(mat[i][j]>mat[i][k]+mat[k][j])

mat[i][j]=mat[i][k]+mat[k][j];

}

}

void make()//把每个任务看成一个点。而不是把每个block看成一个点

{

for(int i=1;i<=m;i++)

{

for(int j=1;j<=m;j++)

{

if(i!=j&&task[i].t+task[i].d+mat[task[i].p][task[j].p]<=task[j].t)

{

//match[task[i].p][task[j].p]=true;

match[i][j]=true;

}

}

}

}

bool dfs(int u)

{

for(int i=1;i<=m;i++)

{

if(!visit[i]&&match[u][i])

{

visit[i]=true;

if(link[i]==-1||dfs(link[i]))

{

link[i]=u;

return true;

}

}

}

return false;

}

int main()

{

while(scanf("%d%d",&q,&m),q!=0||m!=0)

{

memset(match,0,sizeof(match));

memset(mat,0,sizeof(mat));

memset(task,0,sizeof(task));

for(int i=1;i<=q;i++)

for(int j=1;j<=q;j++)

{

scanf("%d",&mat[i][j]);

if(mat[i][j]==-1)

{

mat[i][j]=inf;

}

}

for(int i=1;i<=m;i++)

{

scanf("%d%d%d",&task[i].p,&task[i].t,&task[i].d);

}

floyd();

make();

int ans=0;

memset(link,-1,sizeof(link));

for(int i=1;i<=m;i++)

{

memset(visit,0,sizeof(visit));

if(dfs(i))

ans++;

}

printf("%d\n",m-ans);

}

return 0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: