2019ICPC上海E Cave Escape(最大生成树)

这道题刚开始想到贪心去了,首先所有点都要取到,其次觉得一个点肯定是要跟最大的旁边点相连

但是这里有个问题,就是总是有一个点是原点,也就是这样直接贪心会存在环的情况,这种情况是不允许的,这意味着存在一个点即是出发点也是被遍历点

那么既要消除环的情况,又要连接所有的点,并且要求权值最大,基本上可以想到树

这题其实就是最大生成树问题,我们进一步可以发现,其实每种合法方案就是一颗树,一个点只能被一个点遍历过来,但是他可以对很多点产生贡献

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=2e6+10;
int w[N];
struct node{
    int a,b,w;
    bool operator <(const node &t) const{
        return w<t.w;
    }
}s[N];
int n,m,sr,sc,tr,tc;
int x[N],A,B,C,P;
int a[1010][1010];
int dx[]={0,1};
int dy[]={1,0};
int id[1010][1010];
int tot;
int p[N];
map<int,int> m1;
int find(int x){
    if(p[x]!=x){
        p[x]=find(p[x]);
    }
    return p[x];
}
ll kruscal(){
    sort(s+1,s+1+tot);
    int cnt=0;
    ll res=0;
    for(int i=1;i<=tot;i++){
        int a=s[i].a,b=s[i].b,c=s[i].w;
        int pa=find(a);
        int pb=find(b);
        if(pa!=pb){
            res+=c;
            p[pa]=pb;
            cnt++;
            if(cnt==n*m-1)
                break;
        }
    }
    return res;
}
int main(){
    ios::sync_with_stdio(false);
    int t;
    cin>>t;
    int cas=0;
    while(t--){
        tot=0;
        cin>>n>>m>>sr>>sc>>tr>>tc;
        cin>>x[1]>>x[2]>>A>>B>>C>>P;
        m1.clear();
        int i,j;
        for(i=0;i<=n*m;i++)
            p[i]=i;
        for(i=3;i<=n*m;i++)
            x[i]=(A*x[i-1]+B*x[i-2]+C)%P;
        for(i=1;i<=n;i++){
            for(j=1;j<=m;j++){
                a[i][j]=x[(i-1)*m+j];
            }
        }
        int idx=0;
        for(i=1;i<=n;i++){
            for(j=1;j<=m;j++)
                id[i][j]=++idx;
        }
        int times=0;
        for(i=1;i<=n;i++){
            for(j=1;j<=m;j++){
                for(int k=0;k<2;k++){
                    int tmpx=i+dx[k];
                    int tmpy=j+dy[k];
                    if(tmpx>=1&&tmpx<=n&&tmpy>=1&&tmpy<=m){
                        int dd=id[tmpx][tmpy];
                        int dd1=id[i][j];
                       
                        s[++tot]={dd,dd1,-a[i][j]*a[tmpx][tmpy]};
                    }
                }
            }
        }
        cout<<"Case #"<<++cas<<": "<<-kruscal()<<endl;
    }
    return 0;
}
View Code

 

posted @ 2020-12-04 11:13  朝暮不思  阅读(80)  评论(0编辑  收藏  举报