环游QZ题解--zhengjun

题目描述

F L Y FLY 想要带着他新叫的朋友环游 Q Z QZ ,于是他把 Q Z QZ 划分成了 n n 个地方,已知这 n n 个地方由 m m 条双向边相连接,并且他把 n n 个地方分别赋予了一个 h a p p y happy 值,他希望按照 h a p p y happy 值严格递减 a > b (a>b) 的方法去游览 Q Z QZ ,这样他可以把一些最美的地方介绍给他朋友。如果能够游览的地方数超过10^9+7则输出infinity

输入

第一行两个数 n n m m 表示地方数、边数
第二行n个数表示 n n 个地点的 h a p p y happy
然后m行每行两个数 a a b b 表示 a a b b 之间有一条无向边

输出

一行一个数表示最多能够游览的地方数或者infinity

样例输入

10 30
720472486 1616090782 1659830133 376600248 1485380712 819748825 1072214931 1957734249 95302927 622052677 
2 6 
1 6 
10 2 
8 4 
8 2 
9 6 
1 4 
9 7 
1 4 
4 7 
7 1 
4 5 
10 6 
7 7 
8 5 
7 8 
6 2 
7 2 
3 9 
6 8 
3 4 
9 8 
8 8 
4 5 
8 7 
5 6 
2 2 
9 7 
3 1 
9 1 

样例输出

5

提示

对于10%的数据: 1 < = n < = 10 1 < = m < = 30 1<=n<=10,1<=m<=30
对于30%的数据: 1 < = n < = 500 1 < = m < = 2500 1<=n<=500,1<=m<=2500
对于60%的数据: 1 < = n < = 1000 m < = 3000 1<=n<=1000,m<=3000
对于100%的数据: 1 < = n < = 1 0 5 1 < = m < = 2 1 0 5 1<=n<=10^5,1<=m<=2*10^5 h a p p y happy 值小于等于2^31-1

思路

首先表明,我的思路并不是正解,但是

条条大路通罗马

我的方法也许会给你一点启示。

用一个 f f 数组记录每个地方最多能够游览的地方,数,初始化为1。

首先,我就将各个地方按照 h a p p y happy 值升序排个序,接下来,我就安排序后的顺序,一个一个做。找到能当前节点的所有点,判断是否满足 h a p p y happy 值比当前节点大,如果是,就更新当前节点的 f f 数组 f x = m a x ( f x f t + 1 ) (f_x=max(f_x,f_t+1)) 。最后,在 f f 数组中找一个最大的数,就是答案。

代码

#include<bits/stdc++.h>
#define maxn 100039
#define maxm 1000039
#define max(x,y) (x>y?x:y)
using namespace std;
int n,m;
struct zj{
    int happy,num,ans=1;//happy值,原来的编号,答案
}f[maxn];
int nex[maxm],to[maxm],head[maxn],k;
void add(int a,int b)//链式前向星
{
    to[k]=b;
    nex[k]=head[a];
    head[a]=k++;
    return;
}
bool cmp(const zj &x,const zj &y)
{
    return x.happy<y.happy;
}
int main()
{
    memset(head,-1,sizeof(head));
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
        scanf("%d",&f[i].happy),f[i].num=i;
    for(int i=1;i<=m;i++)
    {
        int x,y;
        scanf("%d%d",&x,&y);
        add(x,y);
        add(y,x);
        //题中说是双向边
    }
    int w[maxn];//记录原来节点的排序后位置
    sort(a+1,a+1+n,cmp);//排序
    for(int i=1;i<=n;i++)
        w[f[i].num]=i;//记录位置
    int ans=0;//最终答案
    for(int i=1;i<=n;i++)
    {
        int pos=head[f[i].num],t=0;
        while(pos!=-1)
        {
            if(f[w[to[pos]]].happy<f[i].happy)//满足题中条件
            t=max(t,f[i].ans+f[w[to[pos]]].ans);//更新当前节点的答案
            pos=nex[pos];
        }
        t=max(t,a[i].ans);
        a[i].ans=t;
        ans=max(ans,t);//更新最终答案
    }
    if(ans>1000000007)cout<<"infinity";
    else cout<<ans;
    return 0;
}

谢谢大家–zhengjun

发布了7 篇原创文章 · 获赞 7 · 访问量 91

猜你喜欢

转载自blog.csdn.net/A_zjzj/article/details/104224192
今日推荐