【hdu 5521】【 2015ACM/ICPC亚洲区沈阳站重现赛】Meeting 题意&题解&代码

题目链接:

http://acm.hdu.edu.cn/showproblem.php?pid=5521

题意:

输入:输入n表示有n个点,输入m表示有m个点集。

接下来m行信息,每行先输入一个t表示这个点集中任意两点费时为t,再输入一个s,表示有s个点在这个点集中,接下来s个数表示这些数在这个点集之中。

现在有两个人,其中一个人住在点1,另一个人住在点n,如果两个人要见面,同时出发,可以走走停停,问需要最少时间是多少,有哪几个点能被当成见面点。

题解:

我们发现这道题如果建好图之后就直接是一个最短路,不管是spfa还是dijkstra,都可以,然而该如何建图呢,我们可以借助拆点的思想,把一个点集看两个点,一个入点和一个出点,将点集中的每个点与入点连一条边长为0的有向边,再将入点和出点连一条边长为t的有向边,最后再将出点与点集中所有点连一条边长为0的有向边,此时再跑两个最短路即可。

代码:

#include<iostream>
#include<algorithm>
#include<stdio.h>
#include<string.h>
#include<vector>
#include<queue>
using namespace std;
int n,m,T;
typedef long long lll;
struct node{
    int v;lll d;
};
node jia(int vv,lll dd)
{
    node a;
    a.v=vv;
    a.d=dd;
    return a;
}
vector<node>lin[300005];
bool vis[300005];
lll dis1[300005],dis2[300005];
void spfa(int s,lll *di)
{
    queue<int>q;
    q.push(s);
    for (int i=1;i<=n+2*m;i++)
    {
        di[i]=1e17+1;
        vis[i]=0;
    }
    di[s]=0;vis[s]=1;
    while(!q.empty())
    {
        int now=q.front();q.pop();
        vis[now]=0;
        //cout<<dis1[now]<<endl;
        for (int i=0;i<lin[now].size();i++)
        {
            int nex=lin[now][i].v;
            int dis=lin[now][i].d;
            //if (nex==5)
            //cout<<now<<endl;
            if (di[now]+dis<di[nex])
            {
                di[nex]=di[now]+dis;
                if (vis[nex]==0)
                {
                    q.push(nex);
                    vis[nex]=1;
                }
            }
        }
    }
}
int main()
{
    scanf("%d",&T);
    for (int t=1;t<=T;t++)
    {
        scanf("%d%d",&n,&m);
        int d,s;
        int tot=n;
        for (int i=1;i<=n+2*m;i++)
        lin[i].clear();
        for (int i=1;i<=m;i++)
        {
            scanf("%d%d",&d,&s);
            tot++;
                        lin[tot].push_back(jia(tot+1,d));
            for (int i=1;i<=s;i++)
            {
                int x;scanf("%d",&x);
                                lin[x].push_back(jia(tot,0));
                                lin[tot+1].push_back(jia(x,0));
            }
            tot++;
        }
        spfa(1,dis1);
        spfa(n,dis2);
        lll ans=1e17;
        for (int i=1;i<=n;i++)
        ans=min(ans,max(dis1[i],dis2[i]));

        if (ans==1e17)
        printf("Case #%d: Evil John\n",t);
        else
        {
            printf("Case #%d: %lld\n",t,ans);
            int flag=0;
            for (int i=1;i<=n;i++)
            if (max(dis1[i],dis2[i])==ans)
            {
                if (flag==0)
                printf("%d",i);
                else
                printf(" %d",i);
                flag=1;
            }
            printf("\n");
        }
    }
}
时间: 2024-12-24 08:46:56

【hdu 5521】【 2015ACM/ICPC亚洲区沈阳站重现赛】Meeting 题意&题解&代码的相关文章

hdu5512 Pagodas(2015ACM/ICPC亚洲区沈阳站-重现赛(感谢东北大学) )

Pagodas Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 14 Accepted Submission(s): 13 Problem Description n pagodas were standing erect in Hong Jue Si between the Niushou Mountain and the Yuntai M

【hdu 5510】【2015ACM/ICPC亚洲区沈阳站-重现赛 】Bazinga 题意&题解&代码(C++)

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5510 题意: 给出n个字符串,求下标最大的字符串,存在下标小于它的字符串中有字符串不是他的子串. 题解: 首先能想到kmp+n^2暴力匹配,但是感觉会超时,因此我们需要加一些剪枝,水题,不要被他的数据范围吓到.. 代码: #include<iostream> #include<algorithm> #include<stdio.h> #include<string.

hdu 5510 Bazinga (kmp+dfs剪枝) 2015ACM/ICPC亚洲区沈阳站-重现赛(感谢东北大学)

废话: 这道题很是花了我一番功夫.首先,我不会kmp算法,还专门学了一下这个算法.其次,即使会用kmp,但是如果暴力枚举的话,还是毫无疑问会爆掉.因此在dfs的基础上加上两次剪枝解决了这道题. 题意: 我没有读题,只是队友给我解释了题意,然后我根据题意写的题. 大概意思是给n个字符串,从上到下依次标记为1——n,寻找一个标记最大的串,要求这个串满足:标记比它小的串中至少有一个不是它的子串. 输入: 第一行输入一个整型t,表示共有t组数据. 每组数据首行一个整型n,表示有n个串. 接下来n行,每行

2015ACM/ICPC亚洲区沈阳站-重现赛 1004 Pagodas

Problem Description: n pagodas were standing erect in Hong Jue Si between the Niushou Mountain and the Yuntai Mountain, labelled from 1 to n. However, only two of them (labelled aand b, where 1≤a≠b≤n) withstood the test of time. Two monks, Yuwgna and

2017ACM/ICPC亚洲区沈阳站-重现赛(感谢东北大学)HDU6225.Little Boxes-大数加法

整理代码... Little Boxes Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)Total Submission(s): 2304    Accepted Submission(s): 818 Problem Description Little boxes on the hillside.Little boxes made of ticky-tacky.Littl

【hdu 5517】【2015ACM/ICPC亚洲区沈阳站】Triple 题意&题解&代码(C++)

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5517 题意: 给出n个二元组<a,b>和m个三元组<c,d,e>现在将其组合成一个新的三元组集合,新三元组中允许有重复元素,一个二元组和一个三元组可以组合当且仅当b==e时将其组合成<a,c,d>,在新组合的三元组中任取一元素<a,b,c>,如果在新组合存在一个元素<u,v,w>使得u!=a && v!=b && w

【hdu 5512】【 2015ACM/ICPC亚洲区沈阳站】Pagodas 题意&题解&代码(C++)

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5512 题意: 给出n个点和a,b两个初始被标记的点,每次可以选取已经被标记点中的两个点 i , j 来标记新点 i+j 或 i-j,两个人轮流标记,如果谁无法标记,谁输,输出赢的人. 题解: 首先我们发现当a,b互质时,它通过以上操作,一定能标记到1号点,接着所有点都可以标记,当a,b不互质时,多写几个数找规律发现gcd(a,b)倍数的位置都可以标记到. 代码: #include<iostream

2016ACM/ICPC亚洲区沈阳站-重现赛

C.Recursive sequence 求ans(x),ans(1)=a,ans(2)=b,ans(n)=ans(n-2)*2+ans(n-1)+n^4 如果直接就去解...很难,毕竟不是那种可以直接化成矩阵的格式,我们也因为这个被卡很长时间 事实上可以把这道式子化成几个基本元素的格式,然后就容易组合了,比如ans(n-2)*2+ans(n-1)+(n-1)^4+4*(n-1)^3+6*(n-1)^2+4*(n-1)^1+1 包含了所有的基本组成形式,化绝对为相对,并且除了一个n-2其他都是n

(HDU 5558) 2015ACM/ICPC亚洲区合肥站---Alice&#39;s Classified Message(后缀数组)

题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=5558 Problem Description Alice wants to send a classified message to Bob. She tries to encrypt the message with her original encryption method. The message is a string S, which consists of Nlowercase let