蒟蒻养成记——简单的数组链表(1)

来源:互联网 发布:中国域名后缀 编辑:程序博客网 时间:2024/05/16 17:17

Graph

1s,256M

【题目描述】

给你一个n个点m条边的无向图,每个点都有自己的颜色Ci

V(k)是一个点集,集合里面的元素是所有颜色为k的点

定义一个集合Q(k),Q(k)={Cu:Cu!=k,如果存在一条边<u,v>,其中v属于V(k)},通俗一点讲就是Q(k)里面的元素是与V(k)相连的点的各种颜色。注意集合里的元素是不重复的。

你的任务是找到一个最小的k,其中Q(k)是最大的。注意你找的k必须是图里存在的颜色。

【输入格式】

第一行n,m

第二行n个数,为每个点对应的颜色

接下来m行描述了一个无向图,保证无自环

【输出格式】

一个数为使Q(k)最大的k,如有多个就输出最小那个

【输入输出样例】

Input1

6 6
1 1 2 3 5 8
1 2
3 2
1 4
4 3
4 5
4 6

Output1

3

Input2

5 6
4 2 5 2 4
1 2
2 3
3 1
5 3
5 4
3 4

Output2

2

 

【数据约定】

60%数据,n,m,ci<=1000

100%数据: n,m,ci<=10^5


【解法】

本题有两种解法:

第一种解法:看到题目,想到图论。这么多相同颜色的点,那就缩点咯。但作为蒟蒻,TJ算法又不会,只能想想玄学的缩点方法。想想从新构图,每种颜色为一个点,比如u点和v点相连,若b【i】表示i的颜色,则在新的图中,b【u】点和b【v】点相连。最后再计算每个点的度,选取最大度的最小颜色点就行了(就是先选度最大的,如果度相同,选颜色小的)


第二种解法:想想,其实和noip2016的普及组第三题有异曲同工之妙,构造简单的链表(数组实现)链表i 表示与颜色i相连的颜色。具体实现上,f 数组存储数字,ff 数组中的 ff【i】表示ff 的后继为 f中的第i 个。然后读入,若u和v相连,若b【i】表示i的颜色,则b【u】放在链表b【v】的最后,b【v】放在链表b【u】的最后。


【代码】只写了第二种解法

#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<iomanip>
using namespace std;
int i,j,k,m,n,o,p,js,jl,u,v,ma,mb,nn;
int a[1001][1001];
int b[100001];
int c[100001];
int f[200001];
int ff[200001];
int g[100001];
int gg[100001]={0};
int main()
{
FILE *fin,*fout;
fin=fopen("graph.in","rb");
fout=fopen("graph.out","wb");
fscanf(fin,"%d%d",&n,&m);
for(int i=1;i<=n;i++)
{
   fscanf(fin,"%d",&b[i]);
   gg[b[i]]=1;
   if(b[i]>nn)nn=b[i];
    }
//==========================================================
if(n<=100000)
    {
    k=0;
    for(int i=1;i<=m;i++)
   {  
   fscanf(fin,"%d%d",&u,&v);
   if(b[v]!=b[u])
   if(g[b[u]]!=0)
   {
    int kk=g[b[u]];
    int pd=0;
    while (true)
    {
    if(f[kk]==b[v])
    {
    pd=1;
    break;
    }
    if(ff[kk]==0)break;
    kk=ff[kk];
    }
    if(pd==0)
    {
    c[b[u]]++;
    k++;
    ff[kk]=k;
    f[k]=b[v];
    }
   }
   if(b[v]!=b[u])
   if(g[b[v]]!=0)
   {
    int kk=g[b[v]];
    int pd=0;
    while (true)
    {
    if(f[kk]==b[u])
    {
    pd=1;
    break;
    }
    if(ff[kk]==0)break;
    kk=ff[kk];
    }
    if(pd==0)
    {
    c[b[v]]++;
    k++;
    ff[kk]=k;
    f[k]=b[u];
    }
   }
   if(b[v]!=b[u])
   if(g[b[u]]==0)
   {
    k++;
    g[b[u]]=k;
    f[k]=b[v];
    c[b[u]]++;
   }
   if(b[v]!=b[u])
   if(g[b[v]]==0)
   {
    k++;
    g[b[v]]=k;
    f[k]=b[u];
    c[b[v]]++;
   }
   
        }
        ma=-1;
        for(int i=1;i<=nn;i++)
   {
       if((c[i]>ma)&&(gg[i]==1))
       {
           ma=c[i];
           mb=i;
            }
        }
    }
fprintf(fout,"%d",mb);
fclose(fin);
fclose(fout);
return 0;
}


0 0
原创粉丝点击