HDOJ--4781--Assignment For Princess【构造有向图】

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

题意:给你两个数,n代表顶点个数,m代表边数,要你建一个图,要求:

1. 有向图,且两个点之间最多只有一条边。

2. 边的权值大小为1~m,每个值只能用一次。

3. 任意一个点都可以到达其余各个顶点。

4. 任意一个环的边上权值之和是3的倍数。

5. 不存在自身环。

思路:先从1顶点到n,相邻两个顶点构造一条有向边,权值分别是1、2、3……n-1,n到1也连一条边,取n、n+1或n+2,取满足权值和是3的倍数的那个值,这样这n个顶点就构成了一个大环,并且满足权值和是3的倍数,因为m的取值最小是n+3,所以这个大环一定能构造出。

对于剩下的m-n条边,假设一条权值为x的有向边要连接u、v两个顶点,则x%3和u、v两顶点间边的权值和sum%3相等才能满足题目要求,如下图所示

顶点{1,2,3,4}是一个环,边的权值和是3的倍数,顶点{1,2,4}也是个环,边的权值和也是3的倍数,因为edge[2][4]替换了edge[2][3]+edge[3][4],只有它们的权值模3相等时才能满足新的环的权值和也是3的倍数。

由于我们构造大环是从小到大构造的,所以添加剩下的m-n条边的时候,边也应该从顶点下标小的点到顶点下标大的点,因为这是有向图,只有这样环才正确。如果图中顶点2、顶点4之间的边是从4到2,虽然(edge[2][4]%3)==(edge[2][3]+edge[3][4])%3,但此时{2,3,4}形成了一个环,显然边的权值和不是3的倍数。

不过经过我测试,这题数据不严谨。就算方向不是从顶点下标小的到顶点下标大的,也能AC

#include<cstring>
#include<string>
#include<fstream>
#include<iostream>
#include<iomanip>
#include<cstdio>
#include<cctype>
#include<algorithm>
#include<queue>
#include<map>
#include<set>
#include<vector>
#include<stack>
#include<ctime>
#include<cstdlib>
#include<functional>
#include<cmath>
using namespace std;
#define PI acos(-1.0)
#define MAXN 110
#define eps 1e-7
#define INF 0x7FFFFFFF
#define seed 131
#define ll long long
#define ull unsigned long long
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1

struct node{
    int u,v,dis;
}edge[10000];
int vis[10000],mapp[90][90],sum[90];
int n,m,cnt,flag;
void gao(int x){
    int i,j;
    for(i=1;i<=n;i++){
        for(j=i+1;j<=n;j++){
            if(!mapp[i][j]&&!mapp[j][i]){
                if((sum[j]-sum[i]+3)%3==x%3){
                    edge[cnt].u = i;
                    edge[cnt].v = j;
                    edge[cnt].dis = x;
                    cnt++;
                    mapp[i][j] = 1;
                    vis[x] = 1;
                    return ;
                }
            }
        }
    }
    flag = 1;
}
int main(){
    int t,i,j,k=1;
    scanf("%d",&t);
    while(t--){
        memset(mapp,0,sizeof(mapp));
        memset(sum,0,sizeof(sum));
        memset(vis,0,sizeof(vis));
        cnt = 0;
        flag = 0;
        int tot = 0;
        scanf("%d%d",&n,&m);
        for(i=1;i<n;i++){
            tot += i;
            edge[cnt].u = i;
            edge[cnt].v = i+1;
            edge[cnt].dis = i;
            vis[i] = 1;
            mapp[i][i+1] = 1;
            cnt++;
            sum[i] = (sum[i-1] + i - 1) % 3;
        }
        edge[cnt].u = n;
        edge[cnt].v = 1;
        if((tot+n)%3==0)    tot = n;
        else if((tot+n+1)%3==0) tot = n + 1;
        else    tot = n + 2;
        edge[cnt].dis = tot;
        vis[tot] = 1;
        mapp[n][1] = 1;
        cnt++;
        sum[n] = (sum[n-1] + n - 1) % 3;
        for(i=1;i<=m;i++){
            if(!vis[i]){
                gao(i);
            }
            if(flag)    break;
        }
        printf("Case #%d:\n",k++);
        if(flag){
            puts("-1");
            continue;
        }
        for(i=0;i<m;i++){
            printf("%d %d %d\n",edge[i].u,edge[i].v,edge[i].dis);
        }
    }
    return 0;
}

HDOJ--4781--Assignment For Princess【构造有向图】

时间: 2024-11-03 05:21:53

HDOJ--4781--Assignment For Princess【构造有向图】的相关文章

HDU 4781 Assignment For Princess(YY乱搞)

http://acm.hdu.edu.cn/showproblem.php?pid=4781 Assignment For Princess Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 639    Accepted Submission(s): 196 Special Judge Problem Description Long

hdu 4781 Assignment For Princess(构造法)

Assignment For Princess Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 958    Accepted Submission(s): 286 Special Judge Problem Description Long long ago, in the Kingdom Far Far Away, there li

hdu4781 Assignment For Princess(构造)

题目链接:hdu4781 Assignment For Princess 题意:n个点m条边,每条有向边的权值分别是1,2,3…m,一个点能到达任意一个点,没有重边和自环,没有任何两条边的权值相同,任意一个有向环的权值和必须是3的倍数,现在需要把这个图输出来. 题解:注意到题目给出的范围m >= n+3,所以一定是可以构造出一个1~n的回路使得权值和为3的倍数的,可以让前n-1条边权值为1~n-1,第n条边(n->1)可以为n, n+1, n+2从而满足题意,后面再连任意两条不相邻的边时,边权

HDOJ 5289 Assignment 单调队列

维护一个递增的和递减的单调队列 Assignment Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 78    Accepted Submission(s): 40 Problem Description Tom owns a company and he is the boss. There are n staffs which a

拓扑排序判断有向图是否有回路

1 #include <iostream> 2 #include <queue> 3 #include <string> 4 using namespace std; 5 6 //表结点 7 typedef struct ArcNode{ 8 int adjvex;//该弧所指向的顶点的位置 9 ArcNode *nextarc; 10 }ArcNode; 11 12 //头结点 13 typedef struct VNode{ 14 string data;//顶点信

WBS任务分解中前置任务闭环回路检测:有向图的简单应用(C#)

1 场景描述 系统中用到了进度计划编制功能,支持从project文件直接导入数据,并能够在系统中对wbs任务进行增.删.改操作.wbs任务分解中一个重要的概念就是前置任务,前置任务设置确定了不同任务项之间的依赖关系,以软件开发的一般过程为例,需求调研就是系统设计的前置任务.具体来说前置任务又分为以下四种类型 Finish-to-Start (FS) 把这个任务的开始日期和前提条件任务的结束日期对齐,一般用于串行的任务安排,前一个任务必须完成后才能启动下一个新任务 Start-to-Start (

有向图的十字链表存储形式

十字链表是有向图的另一种链式存储结构.可以看成是将有向图的邻接表和逆邻接表(只考虑入度)结合起来得到的一种链表.在十字链表中,对应于有向图中每一个顶点有一个节点,每一条弧也有一个结点. 顶点之间是数组顺序存储,而弧是链式存储. 弧结点结构: 顶点结点结构: 十字链表形态: 实现: /*********************************************** 有向图的存储形式--十字链表 by Rowandjj 2014/6/27 ***********************

邻接表求有向图各顶点的入度和出度 (图论基础)

有向图的邻接表用一个结构体LGraph存储表示,其中包括3个成员:顶点数组vertexs,顶点数vexnum和边数arcnum,其中顶点数组vertexs中每个元素都是VNode结构体变量.VNode结构体变量次年初图中每个顶点,它包含3个成员:顶点信息,出边表的表头指针和入边表的表头指针,其中后面两个成员都是ArcNode结构体类型的指针.ArcNode结构体存储边链表中的边节点,它包含两个成员:变的另一个邻接点的序号,以及指向下一个边节点的指针. #define MAXN 100 struc

图的基本操作(基于邻接矩阵):图的构造,深搜(DFS),广搜(BFS)

Adjacency Matrix 邻接矩阵是表示一个图的常用存储表示.它用两个数组分别存储数据元素(顶点)的信息和数据元素之间的关系(边或弧)的信息.阶为n的图G的邻接矩阵A是n*n的.将G的顶点标签为v_1,v_2,...,v_n.若(v_i,v_j) \in E(G),A_{ij}=1,否则A_{ij}=0. Depth-First-Search 是沿着树的深度遍历树的节点,尽可能深的搜索树的分支.当节点v的所有边都己被探寻过,搜索将回溯到发现节点v的那条边的起始节点.这一过程一直进行到已发