1. 程式人生 > >BZOJ3714: [PA2014]Kuglarz

BZOJ3714: [PA2014]Kuglarz

www mst 桌子 幾分鐘 find body 利用 lin lld

[Submit][Status][Discuss]

Description

魔術師的桌子上有n個杯子排成一行,編號為1,2,…,n,其中某些杯子底下藏有一個小球,如果你準確地猜出是哪些杯子,你就可以獲得獎品。花費c_ij元,魔術師就會告訴你杯子i,i+1,…,j底下藏有球的總數的奇偶性。
采取最優的詢問策略,你至少需要花費多少元,才能保證猜出哪些杯子底下藏著球?

Input

第一行一個整數n(1<=n<=2000)。
第i+1行(1<=i<=n)有n+1-i個整數,表示每一種詢問所需的花費。其中c_ij(對區間[i,j]進行詢問的費用,1<=i<=j<=n,1<=c_ij<=10^9)為第i+1行第j+1-i個數。

Output

輸出一個整數,表示最少花費。

Sample Input

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

Sample Output

7 題目傳送門 吃著吃著課間餐,Star_Feel突然跑過來和我講這道題 我咬著雞扒,就只聽到了最小生成樹這個東西 正解也的確是,至於為什麽,是要想上幾分鐘 利用前綴和的思想,那麽其實有三種關系,知道其中兩個就可以知道另一個 而最小生成樹kruskal又把它們拉到了同一個家族裏,所以跑出來的結果肯定是最小的正解 但是為什麽Star_Feel的kruskal跑過去了我T了??? 果然是人醜自帶大常數 我的超時代碼如下:
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
struct node{
    int x,y,next;
    ll d;
}a[4100000];int len;
bool cmp(node a,node b){return a.d<b.d;}
int fa[2100];
int findfa(int
x) { if(fa[x]!=x)fa[x]=findfa(fa[x]); return fa[x]; } int main() { int n; scanf("%d",&n);len=0; for(int i=1;i<=n;i++) for(int j=i;j<=n;j++) { ll x; scanf("%lld",&x);len++; a[len].x=i-1,a[len].y=j,a[len].d=x; } ll ans=0; sort(a+1,a+1+len,cmp); for(int i=0;i<=n;i++)fa[i]=i; for(int i=1;i<=len;i++) { int x=a[i].x,y=a[i].y; int fx=findfa(x),fy=findfa(y); if(fx!=fy) { ans+=a[i].d; fa[fx]=fy; } } printf("%lld\n",ans); return 0; }

Star_Feel的AC代碼如下:
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cstdlib>
using namespace std;
typedef long long LL;
LL c[2100][2100];
struct node
{
    int x,y;LL d;
}a[4100000];int len;
int fa[2100];
int findfa(int x)
{
    if(x!=fa[x]) fa[x]=findfa(fa[x]);
    return fa[x];
}
bool cmp(node n1,node n2)
{
    return n1.d<n2.d;
}
int main()
{
    int n;
    scanf("%d",&n);
    len=0;
    for(int i=1;i<=n;i++)
    {
        for(int j=i;j<=n;j++)
        {
            len++;
            a[len].x=i-1;a[len].y=j;
            scanf("%lld",&a[len].d);
        }
    }
    for(int i=0;i<=n;i++) fa[i]=i;
    sort(a+1,a+len+1,cmp);
    LL ans=0;
    for(int i=1;i<=len;i++)
    {
        int fx=findfa(a[i].x),fy=findfa(a[i].y);
        if(fx!=fy)
        {
            fa[fx]=fy;
            ans+=a[i].d;
        }
    }
    printf("%lld\n",ans);
    return 0;
}

這tm哪有區別啊。。。。。

by_lmy

BZOJ3714: [PA2014]Kuglarz