zoukankan      html  css  js  c++  java
  • HDU4781(2013成都站A题)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4781

    题目大意:给你n个点m条边,要求你构造一个符合条件的有向联通图(若无法构造输出-1,否则输出任意一种方法)

         条件:1.任意两点间只有1条边,且不存在自环,每条边的权值均不相等大小为1~m中的值

            2.从任一点出发可达其他任何一点且可以回到起点

            3.任意一个有向环权值和%3==0

    构造方法:可以先构造一个大环1->2->3->4……->n->1,其中1~n中的每条边权值可以为当前点的序号,可以保证1~n的所有数均被取完

           而n->1的权值则要看前面的所有边的权值和(因为必须满足有向环权值和%3==0),所以当n%3==1时边权值为n+2,否则为n(不懂自己画个图就懂了)

         然后枚举n~m中没有使用过的权值对边进行枚举判断,可行加入答案集,否则输出-1

    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cmath>
    #include <algorithm>
    #include <cstring>
    #include <stack>
    #include <queue>
    #include <string>
    #include <vector>
    #include <set>
    #include <map>
    #include <climits>
    #define lson root<<1,l,mid
    #define rson root<<1|1,mid+1,r
    #define fi first
    #define se second
    #define ping(x,y) ((x-y)*(x-y))
    using namespace std;
    #define gamma 0.5772156649015328606065120 //欧拉常数
    #define MOD 1000000007
    #define inf 0x3f3f3f3f
    #define N 10100000
    #define maxn 1000100
    typedef long long LL;
    typedef pair<int,int> PII;
    
    class Node{
    public:
        int x,y,v;
        Node(){}
        void t(int _x,int _y,int _v){
            x=_x;y=_y;v=_v;
        }
    }node;
    int n,m,d[100][100],vis[1000];
    vector<Node>V;     //答案集合
    
    void init()
    {
        memset(d,0,sizeof(d));
        memset(vis,0,sizeof(vis));   //标记权值是否被访问的数组
        V.clear();
    }
    
    bool add(int &v)
    {
        for(int i=1; i<=n; ++i)
            for(int j=i+1; j<=n; ++j)
                if(!d[i][j]&&(3-(i+j-1)*(j-i)/2%3)%3==v%3)  //这条语句是精髓   (i+j-1)*(j-i)/2%3  它表示从i到j的权值和%3的值
                {                         //再用3去减得到的值表示需要加入余数为3-(i+j-1)*(j-i)/2%3)%3的边才满足条件3
                    node.t(j,i,v);
                    V.push_back(node);
                    d[i][j]=v;
                    vis[v]=1;
                    return true;
                }
        return false;
    }
    
    int main()
    {
        int i,j,group,_max,Case=0,tv;
        scanf("%d",&group);
        while(group--){
            scanf("%d%d",&n,&m);
            init();
            for(i=1; i<n; ++i)
            {
                d[i][i+1]=i;
                node.t(i,i+1,i);
                V.push_back(node);
                vis[i]=1;
            }
            if(n%3==1)
                i+=2;
            vis[i]=1;
            d[1][n]=i;
            node.t(n,1,i);
            V.push_back(node);
            bool flag=true;
            for(i=n; i<=m&&flag; ++i) if(!vis[i])
                flag=add(i);
            printf("Case #%d:
    ",++Case);
            if(!flag){
                puts("-1");
                continue;
            }
            for(i=0; i<m; ++i)
                printf("%d %d %d
    ",V[i].x,V[i].y,V[i].v);
    
        }
        return 0;
    }

    这道题也是咨询了北邮的巨巨之后才理解了的,再次感谢他的帮助.

  • 相关阅读:
    CentOS 5.5 系统安全配置
    从PHP5.2.x迁移到PHP5.3.x
    快要放假了!但为什么现在感到特别的累呢?!
    C#、Oracle、Sql server中拼音查询的函数
    C#实现Word中表格信息读取
    用 win2003 架设共享服务器[3]
    用 win2003 架设共享服务器[2]
    用 win2003 架设共享服务器[1]
    c#操作word表格
    Visual Studio 2008(VS2008)升级正式版
  • 原文地址:https://www.cnblogs.com/Kurokey/p/5308890.html
Copyright © 2011-2022 走看看