HDU--3991[Harry Potter and the Present II] Floyd预处理+最小路径覆盖

 这题只要先用Floyd预处理出任意两点间的最短距离,并且把Q个条件按时间先后从小到大排序,然后遍历任意两个条件a,b;如果node[b].t-node[a].t>=map[node[a].p][node[b].p];则连一条a->b的边,最后求Q个点的最小路径覆盖就可以了~~~~

 

PS.这题时间貌似卡的比较紧,我的代码C++ :TLE   ;  G++:AC  哎 尴尬~~~~

 

 

建图:

void Build()
{
    int i,j,u,v;
    memset(head,-1,sizeof(head));ecnt=0;
    for(i=1;i<=Q;i++)
    {
        for(j=i+1;j<=Q;j++)
        {
            u=node[i].p;
            v=node[j].p;
            if(u==v)
            {
                Insert(i,j);
                continue;
            }
            if(map[u][v]==-1) continue;
            if((node[j].t-node[i].t)>=map[u][v])
                Insert(i,j);
        }
    }
}


 

 

 

CODE:

/*Floyd预处理+最小路径覆盖*/
/*C++:TLE  G++:AC  */
/*AC代码:2648ms*/
#include <iostream>
#include <cstdio>
#include <memory.h>
#include <algorithm>
#define MAXN 2005
#define INF 1e8
#define max(a,b) (a>b?a:b)
#define min(a,b) (a<b?a:b)
using namespace std;
struct Node
{
    int p,t;
}node[MAXN];
struct edge
{
    int u,v,next;
}E[2000000];
int head[MAXN],ecnt;
int N,M,Q,cas;
__int64 map[105][105];
int result[MAXN];
bool flag[MAXN];
void Insert(int u,int v)
{
    E[ecnt].u=u;
    E[ecnt].v=v;
    E[ecnt].next=head[u];
    head[u]=ecnt++;
}
int cmp(const void *p1,const void *p2)
{
    return ((struct Node *)p1)->t-((struct Node *)p2)->t;
}
void Floyd()
{
    int i,j,k;
    for(k=0;k<N;k++)
    {
        for(i=0;i<N;i++)
        {
            if(i==k||map[i][k]==-1) continue;
            for(j=0;j<N;j++)
            {
                if(j==k||j==i||map[k][j]==-1) continue;
                if(map[i][j]==-1||map[i][j]>map[i][k]+map[k][j])
                    map[i][j]=map[i][k]+map[k][j];
            }
        }
    }
}
void Init()
{
    int i,u,v;
    __int64 c;
    scanf("%d%d%d",&N,&M,&Q);
    memset(map,-1,sizeof(map));
    for(i=1;i<=M;i++)
    {
        scanf("%d%d%I64d",&u,&v,&c);
        if(map[u][v]==-1||map[u][v]>c)
        {
            map[u][v]=map[v][u]=c;
        }
    }
    Floyd();
    for(i=1;i<=Q;i++)
        scanf("%d%d",&node[i].p,&node[i].t);
    qsort(node+1,Q,sizeof(node[0]),cmp);
}
void Build()
{
    int i,j,u,v;
    memset(head,-1,sizeof(head));ecnt=0;
    for(i=1;i<=Q;i++)
    {
        for(j=i+1;j<=Q;j++)
        {
            u=node[i].p;
            v=node[j].p;
            if(u==v)
            {
                Insert(i,j);
                continue;
            }
            if(map[u][v]==-1) continue;
            if((node[j].t-node[i].t)>=map[u][v])
                Insert(i,j);
        }
    }
}
bool Find(int u)
{
    int i,v;
    for(i=head[u];i!=-1;i=E[i].next)
    {
        v=E[i].v;
        if(!flag[v])
        {
            flag[v]=true;
            if(result[v]==-1||Find(result[v]))
            {
                result[v]=u;
                return true;
            }
        }
    }
    return false;
}
void Solve()
{
    int i,ans=0;
    Build();//构图
    memset(result,-1,sizeof(result));
    for(i=1;i<=Q;i++)
    {
        memset(flag,false,sizeof(flag));
        ans+=Find(i);
    }
    ans=Q-ans;
    printf("Case %d: %d\n",cas++,ans-1);
}
int main()
{
    int T;
    cas=1;
    scanf("%d",&T);
    while(T--)
    {
        Init();
        Solve();
    }
return 0;
}

你可能感兴趣的:(c,struct,ini,Build,insert)