BZOJ 2139 road
阿新 • • 發佈:2018-09-02
所有 https 比較 clas space stdin putchar efi www. 與\(b\)開來,然後我們分別按他們的值從小到大排序,然後先貪心的進行連邊。這個時候,我們的連邊方式一定是從\(a_i\)屬於的那個國家連向\(b_i\)屬於的那個國家,因為這樣可以保證連出來的邊危險值的最大值最小(這個可以意會一下)。這樣我們就會得到許多小環,然後我們的目的就是把這些小環連成一個大環。所以我們考慮在這些環上加邊,由於我們還要保證環之間的邊能夠盡量的小,所以我們在環之間的邊一定是從\(a_i\)屬於的那個國家連向\(b_{i-1}\)屬於的那個國家(因為如果連向\(b_{i+1}\)所屬的國家的話,那麽\(a_n\)連向的國家一定是\(b_1\)所屬的國家,那樣就沒有之前那種方案連那麽優了)知道這個之後我們就可以對這些環做最小生成樹了,每次連邊的時候更新一下答案就行了,復雜度為\(O(nlogn)\) 。
目錄
- BZOJ 2139 road
- 題意
- 題解
- Code
BZOJ 2139 road
題目傳送門1
題意
很久很久以前,中原地區分成了N個國家,編號為1到N,任意兩個國家都可互達。每個國家有一個攻擊值\(A[i]\)和防禦值\(B[i]\)。定義一個人從i國去j國的危險值為:假如\(A[i]>B[j]\),則危險值為\(( A[i]^2-B[j]^2)\),否則危險值為0。現在,Nan從國家1出發,經過每一個國家有且僅有一次,最後回到國家1,要求找出一種方案,使得其中危險值的最大值最小。
題解
感覺網上的題解好少啊,實際上想通了似乎發現這題還是比較的好寫的,不過仍然還是一道十分妙妙的題目。在看到我們現將所有國家的\(a\)
Code
#include <bits/stdc++.h> using namespace std; typedef long long ll; bool Finish_read; template<class T>inline void read(T &x){Finish_read=0;x=0;int f=1;char ch=getchar();while(!isdigit(ch)){if(ch=='-')f=-1;if(ch==EOF)return;ch=getchar();}while(isdigit(ch))x=x*10+ch-'0',ch=getchar();x*=f;Finish_read=1;} template<class T>inline void print(T x){if(x/10!=0)print(x/10);putchar(x%10+'0');} template<class T>inline void writeln(T x){if(x<0)putchar('-');x=abs(x);print(x);putchar('\n');} template<class T>inline void write(T x){if(x<0)putchar('-');x=abs(x);print(x);} /*================Header Template==============*/ #define PAUSE printf("Press Enter key to continue..."); fgetc(stdin); const int N=1e6+500; const int Md=32767; struct country { int idx,v; bool operator < (const country &rhs) const { return v<rhs.v; } }a[N],b[N],c[N]; int n,x,y,z; int fa[N]; int ans; /*==================Define Area================*/ int Find(int x) {return fa[x]==x?x:fa[x]=Find(fa[x]);} int Sqr(int x) {return x*x;} int main() { read(n); read(a[1].v);read(a[2].v);read(x);read(y);read(z); for(int i=3;i<=n;i++) a[i].v=((ll)x*a[i-1].v+(ll)y*a[i-2].v+z)%Md; read(b[1].v);read(b[2].v);read(x);read(y);read(z); for(int i=3;i<=n;i++) b[i].v=((ll)x*b[i-1].v+(ll)y*b[i-2].v+z)%Md; for(int i=1;i<=n;i++) fa[i]=a[i].idx=b[i].idx=i; sort(a+1,a+1+n);sort(b+1,b+1+n); for(int i=1;i<=n;i++) { ans=max(ans,Sqr(a[i].v)-Sqr(b[i].v)); fa[Find(a[i].idx)]=Find(b[i].idx); } for(int i=2;i<=n;i++) { c[i].v=Sqr(a[i].v)-Sqr(b[i-1].v);c[i].idx=i; } sort(c+1,c+n); for(int i=1;i<n;i++) { int fx=Find(a[c[i].idx].idx),fy=Find(b[c[i].idx-1].idx); if(fx!=fy) ans=max(ans,c[i].v),fa[fx]=fy; } printf("%d\n",ans); return 0; }
BZOJ 2139 road