hdu 3991(最小路径覆盖)

来源:互联网 发布:软件定制开发合同模版 编辑:程序博客网 时间:2024/05/05 19:16

Harry Potter and the Present II

Time Limit: 5000/3000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 195    Accepted Submission(s): 45


Problem Description
Harry and his friends buy a lot of presents now, but they immediately find they had bought too many presents, so they decide to distribute them to the magicians who need them.
To simplify the problem, here we assume the magic world has N cities and M roads, and there are Q requests, at time Ti, someone at city Pi need a present. After planning the route for a while, Harry realizes he can’t do it by himself, he need to find some friends to help him. But the new question is, how many friends Harry should ask at least? We can assume every magician can choose the original city and time to begin his/her journey, and all of them have the same speed, one unit distance per unit time. And if he/she is exactly in city Pi at time Ti, he/she will give the present in a wink, yes, as you see, they are magicians.
 

Input
The first line contains a single integer T, indicating the number of test cases.
Each test case begins with three integers N, M, Q. Then M lines following, each line contains three integers Ai, Bi, Ci, describing an undirected road. Then Q lines following, each line contains two integers Pi, Ti, describing a request.

Technical Specification

1. 1 <= T <= 50
2. 1 <= N <= 100
3. 1 <= M, Q <= 1 000
4. 0 <= Ai, Bi, Pi < N, Ai != Bi
5. 0 <= Ci, Ti <= 1 000 000 000
 

Output
For each test case, output the case number first, then the least friend number.
 

Sample Input
22 1 20 1 10 11 22 1 20 1 20 11 2
 

Sample Output
Case 1: 0Case 2: 1
Hint
If you can’t figure out the sample, think twice whether you have forgotten someone named Harry Potter.
 

Author
iSea@WHU
 

Source
2011 Multi-University Training Contest 15 - Host by WHU
 

Recommend
lcy
 
题目:http://acm.hdu.edu.cn/showproblem.php?pid=3991
PS:这题被坑惨了。。。比赛时很快就发现是最短路径覆盖,却一直因为不明原因wa。。。原来把点到它本身赋值为无穷了,必须赋为零。。。
分析:这题题意看完也是很明显的,先floyd求出所有点之间的距离,之后直接把需求分点就行,之后随便搞吧,记得点到自身的距离赋为0就行
代码:
#include<cstdio>#include<algorithm>using namespace std;const int mm=1111111;const int mn=11111;const int oo=1000000000;int node,src,dest,edge,ret;int ver[mm],flow[mm],next[mm];int head[mn],work[mn],dis[mn],q[mn];double d[111][111];struct data{    int p;    double t;}Q[11111];inline bool cmp(data a,data b){    return a.t<b.t;}inline int min(int a,int b){    return a<b?a:b;}inline void prepare(int _node,int _src,int _dest){    node=_node,src=_src,dest=_dest;    for(int i=0; i<node; ++i)head[i]=-1;    edge=0;}inline void addedge(int u,int v,int c){    ver[edge]=v,flow[edge]=c,next[edge]=head[u],head[u]=edge++;    ver[edge]=u,flow[edge]=0,next[edge]=head[v],head[v]=edge++;}bool Dinic_bfs(){    int i,u,v,l,r=0;    for(i=0; i<node; ++i)dis[i]=-1;    dis[q[r++]=src]=0;    for(l=0; l<r; ++l)        for(i=head[u=q[l]]; i>=0; i=next[i])            if(flow[i]&&dis[v=ver[i]]<0)            {                dis[q[r++]=v]=dis[u]+1;                if(v==dest)return 1;            }    return 0;}int Dinic_dfs(int u,int exp){    if(u==dest)return exp;    for(int &i=work[u],v,tmp; i>=0; i=next[i])        if(flow[i]&&dis[v=ver[i]]==dis[u]+1&&(tmp=Dinic_dfs(v,min(exp,flow[i])))>0)        {            flow[i]-=tmp;            flow[i^1]+=tmp;            return tmp;        }    return 0;}int Dinic_flow(){    int i,ret=0,delta;    while(Dinic_bfs())    {        for(i=0; i<node; ++i)work[i]=head[i];        while(delta=Dinic_dfs(src,oo))ret+=delta;    }    return ret;}int main(){    int i,j,k,u,v,n,m,q,c,t,cas=0,ans;    scanf("%d",&t);    while(t--)    {        scanf("%d%d%d",&n,&m,&q);        for(i=0;i<n;d[i][i]=0,++i)            for(j=0;j<n;++j)d[i][j]=1e20;        while(m--)        {            scanf("%d%d%d",&u,&v,&c);            if(c<d[u][v])d[v][u]=d[u][v]=c;        }        for(i=0;i<q;++i)            scanf("%d%lf",&Q[i].p,&Q[i].t);        for(k=0;k<n;++k)            for(i=0;i<n;++i)                if(k!=j)for(j=0;j<n;++j)                    if(i!=j&&i!=k&&d[i][k]+d[k][j]<d[i][j])d[i][j]=d[i][k]+d[k][j];        sort(Q,Q+q,cmp);        prepare(q+q+2,q+q,q+q+1);        for(i=0;i<q;++i)addedge(src,i,1),addedge(i+q,dest,1);        for(i=0;i<q;++i)            for(j=i+1;j<q;++j)                if(Q[i].t+d[Q[i].p][Q[j].p]-Q[j].t<1e-8)addedge(i,q+j,1);        ans=q-Dinic_flow();        if(ans)--ans;        printf("Case %d: %d\n",++cas,ans);    }    return 0;}


原创粉丝点击