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;
}
不得不是说,这是一道很不错的题目。
刚开始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;
}
相关文章推荐
- POJ3216 floyd+二分图应用(最小路径覆盖)
- POJ - 3216 Repairing Company 二分图 最小路径覆盖
- 二分图最小路径覆盖 POJ 1548、1422、2594、3216
- POJ 3216 Repairing Company【二分图最小路径覆盖】
- POJ-3216-Repairing Company(最小路径覆盖)
- POJ 3020 Antenna Placement(二分图建图训练 + 最小路径覆盖)
- poj 3216 Repairing Company 最小路径覆盖
- 二分图变种之最小路径覆盖、最小点覆盖集【poj3041】【poj2060】
- POJ 3216 Repairing Company(FLOYD+DAG最小路径覆盖)
- POJ 3216 最小路径覆盖+floyd
- POJ 1548 (二分图+最小路径覆盖)
- POJ 1422-Air Raid(二分图_最小路径覆盖)
- poj 2594 Treasure Exploration 可重复覆盖的二分图最小覆盖路径
- POJ 3216 Repairing Company(最小路径覆盖)
- poj 2594 二分图最大匹配最小路径覆盖
- poj 3216 Repairing Company(最短路Floyd + 最小路径覆盖 + 构图)
- poj 3020 二分图最小路径覆盖
- poj 3216 Flyod+最小路径覆盖
- POJ1548 Robots【二分图最小路径覆盖】
- poj 2594 floyd+最小路径覆盖