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;}

原创粉丝点击