2019上海ICPC E.Cave Escape

E.Cave Escape

比賽時候過的人很少,感覺應該是都被卡題了沒有讀這個題,或者榜歪了?

題意:就是說給了一個n * m的矩陣,對於位置(i,j)的能量爲x_(i-1)*m+j
起點在(ex,ey) 終點在(sx,sy) 當你從一個位置第一次走到另一個位置的時候,獲得的值就是這兩個格子能量相乘,每個點可以多次到達,不限制走的步數,就是說你可以隨便走,但獲得的值只能是第一次走到纔有效計算。

思路
要獲得的值最大,又可以隨便走,那最優策略就是把整個矩陣都走一遍··,然後出去就好了。
整個矩陣都走一遍,意味着整個矩陣聯通。也就是把矩陣每個點都抽離出來當作圖的一個點,意味着要求聯通後的最大值。
那不就是最小生成樹嗎
首先把x_(i,j)處理出來,計算每個點與相鄰之間四個點的權值,就是兩點之間的能量相乘。然後跑一次克魯斯卡爾求最大值即可。
對於邊的處理,我們只需要處理當前點與他上邊和左邊的點即可,至於他與右邊和下邊的點,在遍歷的時候也會算進去的,這樣做可以保證不重不漏。

#include<bits/stdc++.h>
using namespace std;
const int maxn=1505;
int p;
int x[maxn*maxn];
int v[maxn][maxn];
struct node
{
    int x,y;
    int v;
}a[maxn*maxn];
int f[maxn*maxn];
int find(int x)
{
    return f[x]==x?x:f[x]=find(f[x]);
}
int main(){
    int t;scanf("%d",&t);
    int cas=0;
    while(t--){
        int n,m,ff,g,h,l;scanf("%d%d%d%d%d%d",&n,&m,&ff,&g,&h,&l);
        int A,B,C;
        scanf("%d%d%d%d%d%d",&x[1],&x[2],&A,&B,&C,&p);
        //處理x_i
        for(int i=3;i<=n*m;i++) x[i]=(A*x[i-1]+B*x[i-2]+C)%p;
         int cnt=0;
         //處理點和邊權值
        for(int i=1;i<=n;i++){
            for(int j=1;j<=m;j++){
                f[(i-1)*m+j]=(i-1)*m+j;
                v[i][j]=x[(i-1)*m+j];
                 if(i-1>=1){
                    a[cnt].x=((i-1)*m+j);
                    a[cnt].y=((i-2)*m+j);
                    a[cnt].v=v[i-1][j]*v[i][j];
                    cnt++;
                }
                if(j-1>=1){
                    a[cnt].x=((i-1)*m+j);
                    a[cnt].y=((i-1)*m+j-1);
                    a[cnt].v=v[i][j-1]*v[i][j];
                    cnt++;
                }
            }
        }
        sort(a,a+cnt,[](node a,node b){
  
            return a.v>b.v;
        });
        long long  sum=0;
        int num=0;
        ///kruscal
        for(int i=0;i<cnt;i++){
            int fx=find(a[i].x),fy=find(a[i].y);
            if(fx!=fy){
                sum+=a[i].v;
                f[fx]=fy;
                num++;
                if(num==n*m-1) break;
            }
        }
        printf("Case #%d: %lld\n",++cas,sum);
  
    }
  
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章