C. Jamie and Interesting Graph

Jamie has recently found undirected weighted graphs with the following
properties very interesting:

The graph is connected and contains exactly n vertices and m edges.
All edge weights are integers and are in range [1, 109] inclusive. The
length of shortest path from 1 to n is a prime number. The sum of
edges' weights in the minimum spanning tree (MST) of the graph is a
prime number. The graph contains no loops or multi-edges. If you are
not familiar with some terms from the statement you can find
definitions of them in notes section.

Help Jamie construct any graph with given number of vertices and edges
that is interesting!

Input First line of input contains 2 integers n, m — the required
number of vertices and edges.

Output In the first line output 2 integers sp, mstw
(1 ≤ sp, mstw ≤ 1014) — the length of the shortest path and the sum of
edges' weights in the minimum spanning tree.

In the next m lines output the edges of the graph. In each line output
3 integers u, v, w (1 ≤ u, v ≤ n, 1 ≤ w ≤ 109) describing the edge
connecting u and v and having weight w.

思路

  • 题意:让我们自己构造一个有n个点、m条边的图,在这个图中 最小生成树的所有在的边权之和为质数,同时节点1到其他节点的最短路径所在的边的边权之(重复的边只能被算一次)和也为质数

  • 思路
    构造方法:我们把这个图构造成一个 长链状的图这样 最小生成树的权值之和 == 所有最短的路径的边权之和,在构造最小生成树的n-1条边的时候,我们让 前n-2条边为的边权均为1,而第n-1那条边,我们选取一个一个数使这个数加上之前的 n-2条边的边权 的和为一个质数,构造完了n-1 的条边之后,可能 构造边的数量还是小于m,那么剩下的边题目上没有要求,我们直接令它们的边权都为一个极大值就行了

代码

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <string>
#include <iostream>
#include <stack>
#include <queue>
#include <vector>
#include <algorithm>
#define mem(a,b) memset(a,b,sizeof(a))
#define inf 0x3f3f3f3f
using namespace std;
const int N=3e5+9;
int prime[N];
bool is_prime[N];
int tot=0;
void get_prime()
{
    mem(is_prime,true);
    is_prime[0]=is_prime[1]=false;
    for(int i=2; i<N; i++)
    {
        if(is_prime[i])
        {
            prime[tot++]=i;
            for(int j=2*i; j<=N; j+=i)
                is_prime[j]=false;
        }
    }
}
int main()
{
    get_prime();
    int n,m;
    scanf("%d%d",&n,&m);
    int num=prime[lower_bound(prime,prime+tot,n-1)-prime];
    int cha=num-n+1;
    int t=m-n+1;
    printf("%d %d\n",num,num);
    for(int i=1; i<=n-1; i++)
    {
        if(i==1)
            printf("%d %d %d\n",i,i+1,cha+1);
        else
            printf("%d %d %d\n",i,i+1,1);
    }
    for(int i=1; i<=n-1; i++)
    {
        for(int j=i+2; j<=n; j++)
        {
            if(t==0) return 0;
            t--;
            printf("%d %d %d\n",i,j,10000000);
        }
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/lql-nyist/p/12737208.html
今日推荐