• hdu 4781 Assignment For Princess (2013ACMICPC 成都站 A)


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


    由于题目太长,这里就不直接贴了,直接说大意吧。

    题目大意:有一个n个点,m条边的有向图,每条边的权值分别为1,2,3........m,让你构造满足下列条件的有向图。

    1:每两个点之间最多只有一条有向边,且不存在自环。

    2:从任意点出发都可以达到其他任意一个点,包括自己。

    3:任意一个有向环的权值和都是3的倍数。


    思路:首先我们可以将点1到n连成一条链,边的权值分别是1到n-1,然后点n到点1连一条边,若n%3为0或2,则边权值为n,否则边权值为n+2(m>=n+3),现在我们构造出了一个环且满足上述三个条件。那么接下来如何构造剩下的m-n条边呢?

    现在我们不管怎么构造都满足第二个条件了,而且现在每个点到自己的距离都是3的倍数。那么如果我要在u,v两点之间连一条全值为len的边,那么只要满足len%3==dist[u][v]%3即可(dist表示原环中两个点之间的距离,自己画一下图应该就能明白),然后在构造的时候还要注意不要违背第一个条件,所以我们可以用map[i][j]来表示i,j之间是否右边,如果按这样构造无法构造出图,则无解。

    代码如下:

    #include <iostream>
    #include <string.h>
    #include <stdio.h>
    #include <algorithm>
    using namespace std;
    int n,m;
    int map[85][85],sum[85],vis[5010];
    int hash[3]={0,2,0};
    struct edge
    {
        int from,to,len;
    }ans[5010];
    int solve(int len,int num)
    {
        int tmp=len%3;
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=n;j++)
            {
                if(i!=j&&!map[i][j]&&!map[j][i])
                {
                    if(j>i)
                    {
                        if((sum[j]-sum[i]+3)%3==tmp)
                        {
                            map[i][j]=1;
                            ans[num].from=i;
                            ans[num].to=j;
                            ans[num].len=len;
                            return 1;
                        }
                    }
                    else
                    {
                        if((sum[i]-sum[j]+3+tmp)%3==0)
                        {
                            map[i][j]=1;
                            ans[num].from=i;
                            ans[num].to=j;
                            ans[num].len=len;
                            return 1;
                        }
                    }
                }
            }
        }
        return 0;
    }
    int main()
    {
        //freopen("dd.txt","r",stdin);
        int ncase,T=0;
        scanf("%d",&ncase);
        while(ncase--)
        {
            memset(vis,0,sizeof(vis));
            memset(map,0,sizeof(map));
            memset(sum,0,sizeof(sum));
            scanf("%d%d",&n,&m);
            sum[1]=0;
            for(int i=1;i<n;i++)
            {
                ans[i].from=i;
                ans[i].to=i+1;
                ans[i].len=i;
                vis[i]=1;
                map[ans[i].from][ans[i].to]=1;
                if(i!=1)
                sum[i]=(sum[i-1]+i-1)%3;
            }
            ans[n].from=n;
            ans[n].to=1;
            map[n][1]=1;
            ans[n].len=n+hash[n%3];
            vis[ans[n].len]=1;
            sum[n]=(sum[n-1]+n-1)%3;
            int num=n,tru=1;
            for(int i=1;i<=m;i++)
            {
                if(!vis[i])
                {
                    tru=solve(i,++num);
                    if(!tru)
                    break;
                }
            }
            printf("Case #%d:
    ",++T);
            if(!tru)
            {
                printf("-1
    ");
                continue;
            }
            for(int i=1;i<=m;i++)
            {
                printf("%d %d %d
    ",ans[i].from,ans[i].to,ans[i].len);
            }
        }
        return 0;
    }


  • 相关阅读:
    Appium+python自动化3-启动淘宝app
    Appium+python自动化2-环境搭建(下)
    Appium+python自动化1-环境搭建(上)
    postman提取返回值
    Android studio(AS)的下载和安装
    monkey的安装和配置
    配置自己的CentOS7服务器
    mac-homebrew安装太慢
    vue.js中祖孙通信之provide与inject
    nginx location 以及 proxy_pass 的几种情况 以/结尾的问题
  • 原文地址:https://www.cnblogs.com/fuhaots2009/p/3429154.html
Copyright © 2020-2023  润新知