首页 > ACM题库 > HDU-杭电 > hdu 3991-harry potter and the present ii-最短路径-[解题报告]hoj
2015
04-14

hdu 3991-harry potter and the present ii-最短路径-[解题报告]hoj

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
2 2 1 2 0 1 1 0 1 1 2 2 1 2 0 1 2 0 1 1 2
 

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

Author
[email protected]
 

Source
 

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

版权声明:本文为博主原创文章,未经博主允许不得转载。


  1. 问题3中,GetRightPosition()和GetLeftPosition()与STL中的upper_bound()和lower_boune()的代码实现一样吗?

  2. 网站做得很好看,内容也多,全。前段时间在博客园里看到有人说:网页的好坏看字体。觉得微软雅黑的字体很好看,然后现在这个网站也用的这个字体!nice!