[BZOJ]3714: [PA2014]Kuglarz
阿新 • • 發佈:2019-02-02
discus find 兩個 ring return NPU getchar problems limit
Submit: 2224 Solved: 1029
[Submit][Status][Discuss]
1 2 3 4 5
4 3 2 1
3 4 5
2 1
5
題解 orz最小生成樹
查詢[l,r]區間需要花費Cij 那麽我們假設有n+1個狀態分別表示前綴查詢 那麽我們對於查詢[i,j]等價於(-1,j)連邊 因為我們可以在Cij花費下 實現兩個前綴狀態的轉移 又已知 我們知道所有前綴狀態時 可以輕易找出每個位置的狀態 所以只需要連邊求MST即可
#include <algorithm> #include <iostream> #include <cstring> #include <cstdio> #include <vector> #include <stack> #include <queue> #include <cmath> #include <set> #include <map> #define mp make_pair #define pb push_back #define pii pair<int,int> #define link(x) for(edge *j=h[x];j;j=j->next) #define inc(i,l,r) for(int i=l;i<=r;i++) #define dec(i,r,l) for(int i=r;i>=l;i--) const int MAXN=2e6+10; const double eps=1e-8; #define ll long long using namespace std; struct edge{int t,v;edge*next;}e[MAXN<<1],*h[MAXN],*o=e; void add(int x,int y,int vul){o->t=y;o->v=vul;o->next=h[x];h[x]=o++;} ll read(){ ll x=0,f=1;char ch=getchar(); while(!isdigit(ch)){if(ch==‘-‘)f=-1;ch=getchar();} while(isdigit(ch))x=x*10+ch-‘0‘,ch=getchar(); return x*f; } typedef struct node{ int u,v,k; friend bool operator<(node aa,node bb){return aa.k<bb.k;} }node; node d[MAXN]; int f[2005]; int find1(int x){ if(x==f[x])return x; return f[x]=find1(f[x]); } int main(){ int n=read(); int cnt=0,k; inc(i,1,n){ inc(j,i,n){ d[++cnt]=(node){i,j+1,k=read()}; } } sort(d+1,d+cnt+1); ll ans=0; inc(i,1,n+1)f[i]=i; inc(i,1,cnt){ int t1=find1(d[i].u);int t2=find1(d[i].v); if(t1==t2)continue; f[t1]=t2;ans+=d[i].k; } printf("%lld\n",ans); }
3714: [PA2014]Kuglarz
Time Limit: 20 Sec Memory Limit: 128 MBSubmit: 2224 Solved: 1029
[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
51 2 3 4 5
4 3 2 1
3 4 5
2 1
5
Sample Output
7[BZOJ]3714: [PA2014]Kuglarz