POJ1944

poj1944

一道我不会做的贪心题。

(思维才是OI的重点)

但是if您也不会,那就来听我瞎扯吧。

首先,这个图是一个圈,只能连接邻点,使所有求的点联通。

我们先不考虑环,那么就可以想出一个假的做法:用一个a数组记录入度和出度,出度为正,入度为负,用一个sum=0从0遍历每个点记录当前出入度,每次加ai,若sum大于0给答案加上1就行了。

然后,我们来考虑环。我们发现。不管怎么连这个图,肯定都会有一个断边的,连接的路径绝不会是一个完整的环。因为如果连成了完整地环,肯定有一条边断掉这个图还是联通的,即这条边是无用的。那么,我们欺负n小就可以分别从第i个点出发像上述查找一条链的做法一样地计算,然后取最大值就行了。

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cctype>
using namespace std;
inline int read()
{
    int x=0,w=0;char c=getchar();
    while(!isdigit(c))w|=c=='-',c=getchar();
    while(isdigit(c))x=(x<<3)+(x<<1)+(c^48),c=getchar();
    return w?-x:x;
}
const int maxn=1010,maxm=10010;
int n,m,a[maxn],l[maxm],r[maxm];
int main()
{
    n=read(),m=read();
    for(int i=0;i<m;i++)l[i]=read(),r[i]=read();
    int ans=0x3f3f3f3f;
    for(int i=0;i<n;i++){
        memset(a,0,sizeof a);
        int x,y;
        for(int j=0;j<m;j++){
            x=(l[j]+i)%n;
            y=(r[j]+i)%n;
            if(x>y)swap(x,y);
            a[x]++;
            a[y]--;
        }
        int now=0,pre=0;
        for(int i=0;i<n;i++){
            now+=a[i];
            if(now)pre++;
        }
        if(pre<ans)ans=pre;
    }
    printf("%d
",ans);
    return 0;
}
原文地址:https://www.cnblogs.com/BrotherHood/p/13359001.html