zoukankan      html  css  js  c++  java
  • 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
    没有人不辛苦,只有人不喊疼
  • 相关阅读:
    动态创建DeepZoom
    MultiSheet Excel Output
    PL/SQL Developer设置技巧
    采购审批专题总结bob
    oracle dbms包和其他包的使用大全
    ARAuto Invoice question
    应收发票相关 脚本
    发运确认停靠站错误
    让R12直接从Form登录
    查找事物处理来源
  • 原文地址:https://www.cnblogs.com/ctyakwf/p/14084772.html
Copyright © 2011-2022 走看看