开始的时候,没有注意到最短路(因为有些城市本来是不可以直达的,但是floyd一次之后,本来不能直达的,可以路过其他城市,再到达目的地),wa了一次,
先用floyd求出来,然后就是最小路径的问题了
图论给我的感觉,构图只有你想不到,没有做不到,这从侧面印证了图论的强大。。。。题还是做得太少了
#include<stdio.h>
#include<string.h>
#include<vector>
#define INF 1<<25
#define val 500
using namespace std;
typedef struct node
{
int block,cost,deadline;
}job;
int match[val],n,m,map[21][21];
bool in[val];
vector<int> link[val];
vector<job> node;
void create_link();//构图
int hungary();//最大匹配
int main()
{
int ans;
while(scanf("%d %d",&n,&m)&&n+m)
{
node.clear();
create_link();
ans=hungary();
printf("%d\n",node.size()-ans);//最小路径覆盖=定点数-最大匹配
}
return 0;
}
void create_link()
{
int i,k,j,a,b,c,end;
job p;
node.clear();
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
{
scanf("%d",&map[i][j]);
if(map[i][j]==-1) map[i][j]=INF;
}
for(k=1;k<=n;k++)//floyd
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
if(map[i][j]>map[i][k]+map[k][j])
map[i][j]=map[i][k]+map[k][j];
for(i=0;i<m;i++) link[i].clear();
for(i=0;i<m;i++)
{
scanf("%d %d %d",&a,&b,&c);
p.block=a;
p.deadline=b;
p.cost=c;
node.push_back(p);
}
for(i=0;i<node.size();i++)
{
if(i==j) continue;
end=node[i].deadline+node[i].cost-1;
for(j=0;j<node.size();j++)
{
if(map[node[i].block][node[j].block]==-1) continue;
if(end+map[node[i].block][node[j].block]<node[j].deadline)
link[i].push_back(j);
}
}
}
int hungary()
{
bool dfs(int);
int i,sum=0;
memset(match,-1,sizeof(match));
for(i=0;i<node.size();i++)
{
memset(in,false,sizeof(in));
if(dfs(i)) sum++;
}
return sum;
}
bool dfs(int x)
{
int i,index,temp;
for(i=0;i<link[x].size();i++)
{
index=link[x][i];
if(!in[index])
{
in[index]=true;
temp=match[index];
match[index]=x;
if(temp==-1||dfs(temp)) return true;
match[index]=temp;
}
}
return false;
}