hdu 3991 Harry Potter and the Present II
来源:互联网 发布:美空网怎么约 知乎 编辑:程序博客网 时间:2024/06/05 02:22
最小点覆盖:先用弗洛伊德算法把每两个城市的最短距离算出来,然后把分配的任务按时间排序,如果完成一个任务后,还可以在规定的时间内完成另一个任务,那么就在这两个任务编号之间连一条边,然后运行匈牙利算法,用任务总数减去得出来的数,当然要在减去1,他自己除外。#include<stdio.h>#include<string.h>#include<iostream>using namespace std;struct node{int time;int city;}dis[1010];const int inf=1000000010;__int64 map[110][110];int f[1200][1200],vis[1200],link[1200];int n,m,q,ans,t,tot,start,end,len;bool cmp(node a,node b){ return a.time<b.time;}bool dfs(int v){ for(int i=0;i<q;i++) { if(f[v][i]==1&&vis[i]==0) { vis[i]=1; if( link[i]==-1 || dfs(link[i]) ) { link[i]=v; //cout<<i<<' '<<v<<endl; return true; } } } return false;} int path(){ ans=0; for(int i=0;i<q;i++) link[i]=-1; for(int i=0;i<q;i++) { for(int j=0;j<q;j++) vis[j]=0; if(dfs(i)) ans++; } return ans;} int main(){ scanf("%d",&tot); for(int t=1;t<=tot;t++) { scanf("%d%d%d",&n,&m,&q); for(int i=0;i<n;i++) for(int j=0;j<n;j++) { map[i][j]=inf; map[i][i]=0; } for(int i=0;i<m;i++) { scanf("%d%d%I64d",&start,&end,&len); if(map[start][end]>len) { map[start][end]=len; map[end][start]=len; } } for(int i=0;i<q;i++) scanf("%d%d",&dis[i].city,&dis[i].time); for(int k=0;k<n;k++) for(int i=0;i<n;i++) for(int j=0;j<n;j++) { if(map[i][j]>map[i][k]+map[k][j]) map[i][j]=map[i][k]+map[k][j]; } sort(dis,dis+q,cmp); for(int i=0;i<q;i++) for(int j=0;j<q;j++) f[i][j]=0; for(int i=0;i<q;i++) for(int j=i+1;j<q;j++) { if(dis[j].time-dis[i].time>=map[dis[j].city][dis[i].city]) { f[i][j]=1; } } printf("Case %d: %d\n",t,q-path()-1); } return 0;}