zoukankan      html  css  js  c++  java
  • Codeforces 589H Tourist Guide (NEERC 2015 H题)

    H. Tourist Guide
    time limit per test
    2 seconds
    memory limit per test
    512 megabytes
    input
    standard input
    output
    standard output

    It is not that easy to create a tourist guide as one might expect. A good tourist guide should properly distribute flow of tourists across the country and maximize the revenue stream from the tourism. This is why there is a number of conditions to be met before a guide may be declared as an official tourist guide and approved by Ministry of Tourism.

    Ministry of Tourism has created a list of k remarkable cities out of n cities in the country. Basically, it means that in order to conform to strict regulations and to be approved by the ministry a tourist guide should be represented as a set of routes between remarkable cities so that the following conditions are met:

    • the first and the last city of every route are distinct remarkable cities,
    • each remarkable city can be an endpoint of at most one route,
    • there is no pair of routes which share a road.

    Please note that a route may pass through a remarkable city. Revenue stream from the tourism highly depends on a number of routes included in a tourist guide so the task is to find out a set of routes conforming the rules of a tourist guide with a maximum number of routes included.

    Input

    The first line contains three integer numbers n,  m,  k (1 ≤ n ≤ 50000,  0 ≤ m ≤ 50000,  1 ≤ k ≤ n) — the number of cities in the country, the number of roads in the country and the number of remarkable cities correspondingly.

    Each of the following m lines contains two integer numbers ai and bi (1 ≤ ai, bi ≤ n) — meaning that cities ai and bi are connected by a bidirectional road. It is guaranteed that ai and bi are distinct numbers and there is no more than one road between a pair of cities.

    The last line contains k distinct integer numbers — a list of remarkable cities. All cities are numbered from 1 to n.

    Output

    The first line of the output should contain c — the number of routes in a tourist guide. The following c lines should contain one tourist route each. Every route should be printed in a form of "t v1 v2 ... vt + 1", where t is a number of roads in a route and v1,  v2, ..., vt + 1 — cities listed in the order they are visited on the route.

    If there are multiple answers print any of them.

    Sample test(s)
    input
    6 4 4
    1 2
    2 3
    4 5
    5 6
    1 3 4 6
    
    output
    2
    2 1 2 3
    2 4 5 6
    
    input
    4 3 4
    1 2
    1 3
    1 4
    1 2 3 4
    
    output
    2
    1 1 2
    2 3 1 4



    这个题当时也没做出来 赛后听zb大爷讲过写出来了

    首先orz zb srm 岛娘 今天沈阳regional取的亚军


    题目大意是 有一个图 有一些点是带标记的

    让你求最多的路径 要求

    1.路径上的起点和终点都是带标记的

    2.每个带标记的点只能作为最多一条路径的端点

    3.两条路径不能有公共边


    转化到树上做

    对于每个子树 、

    如果恰有偶数个标记的点 一定可以在子树内相互连接到达

    如果有奇数个标记的点 就把多的那个点尝试通过子树的父亲连接


    看代码很简单 就是挺难想的。。

    dfs返回以u为根的子树中最后一个没被匹配的带标记的点

    如果没有 返回-1

    如果有 尝试与其他子树的最后一个没被匹配的点作为路径

    #include<bits/stdc++.h>
    using namespace std;
    const int lim=50011;
    int m,tn,q,n;
    
    struct self
    {
        int x,y,nxt;
    }s[lim<<1];
    
    int fa[lim];
    int flag[lim];
    int x,y;
    int remark[lim];
    int fst[lim];
    vector<int>g[lim];
    int ans;
    void add(int x,int y)
    {
        n++;
        s[n].x=x;
        s[n].y=y;
        s[n].nxt=fst[x];
        fst[x]=n;
    }
    void makel(int ans,int f,int t)
    {
        for(int e=f;e!=t;e=fa[e])
            g[ans].push_back(e);
        g[ans].push_back(t);
    }
    void maker(int ans,int t,int f)
    {
        if(t==f)
            return;
        maker(ans,fa[t],f);
        g[ans].push_back(t);
    }
    void make(int l,int root)
    {
        ans++;
        makel(ans,l,root);
    }
    void make(int l,int root,int r)
    {
        ans++;
        makel(ans,l,root);
        maker(ans,r,root);
    }
    int dfs(int u,int ff)
    {
        fa[u]=ff;
        flag[u]=1;
        int f1=-1,f2=-1;
        for(int e=fst[u];e!=-1;e=s[e].nxt)
        {
            int v=s[e].y;
            if(!flag[v])
            {
                if(f1==-1)
                    f1=dfs(v,u);
                else
                    f2=dfs(v,u);
                if(f1!=-1 && f2!=-1)
                {
                    make(f1,u,f2);
                    f1=f2=-1;
                }
            }
        }
        if(remark[u])
        {
            if(f1!=-1)
            {
                make(f1,u);
                return -1;
            }
            else
                return u;
        }
        else
            if(f1!=-1)
                return f1;
            else
                return -1;
    }
    
    int main()
    {
        scanf("%d%d%d",&m,&tn,&q);
        memset(fst,-1,sizeof(fst));
        n=0;
        for(int i=1;i<=tn;i++)
        {
            scanf("%d%d",&x,&y);
            add(x,y);
            add(y,x);
        }
        for(int i=1;i<=q;i++)
        {
            scanf("%d",&x);
            remark[x]=1;
        }
        for(int i=1;i<=m;i++)
            if(!flag[i])
                dfs(i,-1);
        printf("%d
    ",ans);
        for(int i=1;i<=ans;i++)
        {
            int len=g[i].size();
            printf("%d ",len-1);
            for(int j=0;j<len-1;j++)
                printf("%d ",g[i][j]);
            printf("%d
    ",g[i][len-1]);
        }
        return 0;
    }



  • 相关阅读:
    socket 中文man页面函数
    指针和数组(上)
    char和unsigned char--数据类型区别
    自己的总结
    warning C4305:“初始化”:从“double”到“float”截断
    指针数组和数组指针区别
    Python模块常用的几种安装方式
    Jenkins环境搭建
    wxPython:事件
    wx.ListCtrl简单使用例子
  • 原文地址:https://www.cnblogs.com/abgnwl/p/6550334.html
Copyright © 2011-2022 走看看