洛谷 P3505 [POI2010]TEL-Teleportation

题目描述

King Byteasar is the ruler of the whole solar system that contains  planets.

This number is so large that people have abandoned the silly custom of naming the planets and use numbers instead. The planets are thus conveniently numbered from 1 to .

Byteasar's palace is on the planet no. 1, while his military base on the planet no. 2.

A long time ago Byteasar had a teleportation portal established between these two planets, which allows travelling from either planet to another in two hundred and fifty minutes (slightly over four hours).

Nowadays the teleportation technology is more mature, and the recent teleportation devices shorten the travel time to just a single hour. Let us note here, that all the portals, both the Byteasar's old one and the new ones available on the market, are of course bidirectional, and that the teleportation travel time is irrespective of the distance travelled.

Some planets of the system are already connected with these new teleportation portals.

In fact, it is already possible to travel between the planets no. 1 and 2 without using the king's private portal, though this involves several other portals and is thus no faster than the king's portal.

Byteasar finds this rather fortunate, as he believes that such possibility would be a security breach.

The technology itself is increasingly available, and as everyone realises its economic significance, each pair of planets that are not currently directly connected with a portal are petitioning for establishing such a connection. Being a wise ruler, Byteasar intends to give his consent to as many constructions as possible, though keeping himself secure, i.e., not allowing the travel between planets 1 and 2 faster than with his private portal.

Help the king determine how many portals he can agree to.

给一张图,要求你再尽可能的多连边,使得从1到2至少要经过5条边

输入输出格式

输入格式:

 

Two integers are given in the first line of the standard input,  and  (), separated by a single space, denoting the number of planets in Byteasar's realm and the number of new portals that already exist.

These teleportation portals are described in the  lines that follow.

Each such line contains two integers  and  (), separated by a single space, denoting that there is a teleportation portal of the new kind connecting  and .

No pair of numbers appears twice.

You may assume that the existing network of new portals allows travel from planet no. 1 to planet no. 2, but in no less than 250 minutes.

 

输出格式:

 

Your program should print out just a single integer, namely the maximum number of portals Byteasar can agree to without breaching his security.

 

输入输出样例

输入样例#1: 复制
10 10
1 3
3 5
5 7
7 9
2 9
1 4
4 6
6 8
8 10
2 10
输出样例#1: 复制
10
思路:假设已经完成了所有的建图。
那我可以把最后得到的图中的n个点划分为6个集合:1所在的集合,A,B,C,D,2所在的集合
相邻的两个集合之间的所有的点有连边,同一个集合里的各个点之间有连边,其余的没有边。
首先可以证明1所在的集合={1},因为如果放入了其他的点,他就只能和1还有A连边。
但是如果打他放在A里,他就可以和1,A中所有的点,B中所有的点连边。
同理,可以证明2所在的集合={2};
然后会惊讶的发现,在1和2所在的集合确定好了之后,集合A,D也随之确定了。
因为只有A集合中的点才能向1连边,所以在原图中与1相连的点一定在A集合中,其他的点一定可以不在A集合中(因为C集合不为空集)。
同理,集合D也可以得到。
然后考虑剩下的点,他们两两之间肯定有边相连,所以我们要做的就是让他们尽可能多的向外连边,他们向外连边只有两种情况:
  1.分到B集合里向A连边。
  2.分到C集合里向D连边。
所以在原图中,与A集合中的点有连边的点一定会被分到B集合中。与D集合中的点有连边的点一定会被分到C集合中。
剩下的点一定是按照最优策略分到能连出尽可能多的边的点集中,也就是说,如果A重点的数量比D中的多,就把这些点分到B中,反之分到C中。
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define MAXN 1000010
using namespace std;
int n,m,tot,ans;
int tmp1,tmp2;
int tot1,tot2,tot3;
int belong[MAXN];
int to[MAXN*2],net[MAXN*2],head[MAXN];
void add(int u,int v){
    to[++tot]=v;net[tot]=head[u];head[u]=tot;
    to[++tot]=u;net[tot]=head[v];head[v]=tot;
}
int main(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++){
        int u,v;
        scanf("%d%d",&u,&v);
        add(u,v);
    }
    for(int i=head[1];i;i=net[i])
        tot1++,belong[to[i]]=1;
    for(int i=head[2];i;i=net[i])
        tot2++,belong[to[i]]=2;
    tot3=n-tot1-tot2-2;
    ans=tot1*(tot1-1)/2+tot2*(tot2-1)/2+tot3*(tot3-1)/2+tot1+tot2;
    for(int x=3;x<=n;x++)
        if(!belong[x])
            for(int i=head[x];i;i=net[i]){
                if(!belong[to[i]])    continue;
                if(belong[to[i]]==1)    tmp1++;
                else tmp2++;
                break;
            }
    ans+=tmp1*tot1+tmp2*tot2+(tot3-tmp1-tmp2)*max(tot1,tot2);
    cout<<ans-m;
}

 

 
posted @ 2017-11-06 10:43  一蓑烟雨任生平  阅读(449)  评论(0编辑  收藏  举报