Andrew Stankevich Contest 2 (ASC 2) |我为什么要开这套题
来源:互联网 发布:26岁出国读研 知乎 编辑:程序博客网 时间:2024/06/01 09:51
F Roads
某个国家有石头路和烂泥路,石头路恰好是生成树,维护路自然是花钱的,现在希望通过修改路的维护费用使得石头路是最小生成树(可以不是唯一的MST),目标是总的修改量最小,要求输出方案。
设石头路的修改后权值为w[i]-d[i]
烂泥路的修改后权值为w[i]+d[i]
对于1条烂泥路x,恰对应了MST中一条链,显然它权值要大于上面的任意一条边y。
原问题变为2分图最小权覆盖(Minimum Weighted Cover)
这可以用KM解决。
#include<bits/stdc++.h> using namespace std;#define For(i,n) for(int i=1;i<=n;i++)#define Fork(i,k,n) for(int i=k;i<=n;i++)#define ForkD(i,k,n) for(int i=n;i>=k;i--)#define Rep(i,n) for(int i=0;i<n;i++)#define ForD(i,n) for(int i=n;i;i--)#define RepD(i,n) for(int i=n;i>=0;i--)#define Forp(x) for(int p=pre[x];p;p=next[p])#define Forpiter(x) for(int &p=iter[x];p;p=next[p]) #define Lson (o<<1)#define Rson ((o<<1)+1)#define MEM(a) memset(a,0,sizeof(a));#define MEMI(a) memset(a,0x3f,sizeof(a));#define MEMi(a) memset(a,128,sizeof(a));#define MEMx(a,b) memset(a,b,sizeof(a));#define INF (0x3f3f3f3f)#define F (1000000007)#define pb push_back#define mp make_pair#define fi first#define se second#define vi vector<int> #define pi pair<int,int>#define SI(a) ((a).size())#define Pr(kcase,ans) printf("Case #%d: %lld\n",kcase,ans);#define PRi(a,n) For(i,n-1) cout<<a[i]<<' '; cout<<a[n]<<endl;#define PRi2D(a,n,m) For(i,n) { \ For(j,m-1) cout<<a[i][j]<<' ';\ cout<<a[i][m]<<endl; \ } #pragma comment(linker, "/STACK:102400000,102400000")#define ALL(x) (x).begin(),(x).end()#define gmax(a,b) a=max(a,b);#define gmin(a,b) a=min(a,b);typedef long long ll;typedef long double ld;typedef unsigned long long ull;ll mul(ll a,ll b){return (a*b)%F;}ll add(ll a,ll b){return (a+b)%F;}ll sub(ll a,ll b){return ((a-b)%F+F)%F;}void upd(ll &a,ll b){a=(a%F+b%F)%F;}inline int read(){ int 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;} #define MAXN 500int fa[MAXN],wfa[MAXN],idefa[MAXN];vi e[MAXN],wei[MAXN],id[MAXN];int dep[MAXN]; void dfs(int x,int f,int d) { fa[x]=f; dep[x]=d; Rep(i,SI(e[x])) { int v=e[x][i],w=wei[x][i],idd=id[x][i]; if (v^f){ wfa[v]=w; idefa[v]=idd; dfs(v,x,d+1); } }}int f[MAXN][MAXN];int u[MAXN],v[MAXN],w[MAXN];namespace KM{ const int N=405; const ll inf=~0U>>1; int n,nl,nr,m,z,py,x,y,i,j,p,lk[N],pre[N]; bool vy[N]; int lx[N],ly[N],d,w[N][N],slk[N];ll ans; int work(int nl,int nr){ // nl nr w n=max(nl,nr); For(i,nl) For(j,nr) w[i][j]=max(0,f[i][j]);// while(m--)scanf("%d%d%d",&x,&y,&z),w[y][x]=max(w[y][x],z); for(i=1;i<=n;i++)for(j=1;j<=n;j++)lx[i]=max(lx[i],w[i][j]); for(i=1;i<=n;i++){ for(j=1;j<=n;j++)slk[j]=inf,vy[j]=0; for(lk[py=0]=i;lk[py];py=p){ vy[py]=1;d=inf;x=lk[py]; for(y=1;y<=n;y++)if(!vy[y]){ if(lx[x]+ly[y]-w[x][y]<slk[y])slk[y]=lx[x]+ly[y]-w[x][y],pre[y]=py; if(slk[y]<d)d=slk[y],p=y; } for(y=0;y<=n;y++)if(vy[y])lx[lk[y]]-=d,ly[y]+=d;else slk[y]-=d; } for(;py;py=pre[py])lk[py]=lk[pre[py]]; } for(i=1;i<=n;i++)ans+=lx[i]+ly[i];// printf("%lld\n",ans);// for(i=1;i<=nl;i++)printf("%d ",w[lk[i]][i]?lk[i]:0); }}int n,m;void prekm(int x,int y,int p) { if (dep[x]<dep[y]) swap(x,y); while(dep[x]>dep[y]) { f[idefa[x]][p]=-w[p+n-1]+wfa[x]; x=fa[x]; } while(x^y) { f[idefa[x]][p]=-w[p+n-1]+wfa[x]; f[idefa[y]][p]=-w[p+n-1]+wfa[y]; x=fa[x]; y=fa[y]; }}int main(){ freopen("roads.in","r",stdin); freopen("roads.out","w",stdout); n=read(),m=read(); For(i,n-1) { int u=read(),v=read(),w=read(); e[u].pb(v);e[v].pb(u); wei[u].pb(w);wei[v].pb(w); id[u].pb(i); id[v].pb(i); ::w[i]=w;::u[i]=u;::v[i]=v; } dfs(1,0,1); MEM(f) Fork(i,n,m) { u[i]=read(),v[i]=read();w[i]=read(); prekm(u[i],v[i],i-n+1); } KM::work(n-1,m-n+1); For(i,n-1) { printf("%d\n",w[i]-KM::lx[i]); } Fork(i,n,m) { printf("%d\n",w[i]+KM::ly[i-n+1]); } return 0;}
H
一张票有N*M的黑白格子,可以卷成圆柱(cylinder)再卷成环,问这样操作后依然不同构的票有多少种。(n,m<=20)
根据伯恩赛德定理,等价类个数=置换集合中的每个置换不动点个数C(f)的平均值.
当n!=m时,有左移,上移,转180度,3种置换(互不影响)。
等价类个数=
这题n=m时,还可以旋转90度。
等价类个数=
#include<bits/stdc++.h> using namespace std;#define For(i,n) for(int i=1;i<=n;i++)#define Fork(i,k,n) for(int i=k;i<=n;i++)#define ForkD(i,k,n) for(int i=n;i>=k;i--)#define Rep(i,n) for(int i=0;i<n;i++)#define ForD(i,n) for(int i=n;i;i--)#define RepD(i,n) for(int i=n;i>=0;i--)#define Forp(x) for(int p=pre[x];p;p=next[p])#define Forpiter(x) for(int &p=iter[x];p;p=next[p]) #define Lson (o<<1)#define Rson ((o<<1)+1)#define MEM(a) memset(a,0,sizeof(a));#define MEMI(a) memset(a,0x3f,sizeof(a));#define MEMi(a) memset(a,128,sizeof(a));#define MEMx(a,b) memset(a,b,sizeof(a));#define INF (0x3f3f3f3f)#define F (1000000007)#define pb push_back#define mp make_pair#define fi first#define se second#define vi vector<int> #define pi pair<int,int>#define SI(a) ((a).size())#define Pr(kcase,ans) printf("Case #%d: %lld\n",kcase,ans);#define PRi(a,n) Rep(i,n-1) cout<<a[i]<<' '; cout<<a[n-1]<<endl;#define PRi2D(a,n,m) For(i,n) { \ For(j,m-1) cout<<a[i][j]<<' ';\ cout<<a[i][m]<<endl; \ } #pragma comment(linker, "/STACK:102400000,102400000")#define ALL(x) (x).begin(),(x).end()#define gmax(a,b) a=max(a,b);#define gmin(a,b) a=min(a,b);typedef long long ll;typedef long double ld;typedef unsigned long long ull;ll mul(ll a,ll b){return (a*b)%F;}ll add(ll a,ll b){return (a+b)%F;}ll sub(ll a,ll b){return ((a-b)%F+F)%F;}void upd(ll &a,ll b){a=(a%F+b%F)%F;}inline int read(){ int 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;} int gcd(int a,int b){ return (!b)?a:gcd(b,a%b);}struct BigInteger { typedef unsigned long long LL; static const int BASE = 100000000; static const int WIDTH = 8; vector<int> s; BigInteger& clean(){while(!s.back()&&s.size()>1)s.pop_back(); return *this;} BigInteger(LL num = 0) {*this = num;} BigInteger(string s) {*this = s;} BigInteger& operator = (long long num) { s.clear(); do { s.push_back(num % BASE); num /= BASE; } while (num > 0); return *this; } BigInteger& operator = (const string& str) { s.clear(); int x, len = (str.length() - 1) / WIDTH + 1; for (int i = 0; i < len; i++) { int end = str.length() - i*WIDTH; int start = max(0, end - WIDTH); sscanf(str.substr(start,end-start).c_str(), "%d", &x); s.push_back(x); } return (*this).clean(); } BigInteger operator + (const BigInteger& b) const { BigInteger c; c.s.clear(); for (int i = 0, g = 0; ; i++) { if (g == 0 && i >= s.size() && i >= b.s.size()) break; int x = g; if (i < s.size()) x += s[i]; if (i < b.s.size()) x += b.s[i]; c.s.push_back(x % BASE); g = x / BASE; } return c; } BigInteger operator - (const BigInteger& b) const { assert(b <= *this); // ¼õÊý²»ÄÜ´óÓÚ±»¼õÊý BigInteger c; c.s.clear(); for (int i = 0, g = 0; ; i++) { if (g == 0 && i >= s.size() && i >= b.s.size()) break; int x = s[i] + g; if (i < b.s.size()) x -= b.s[i]; if (x < 0) {g = -1; x += BASE;} else g = 0; c.s.push_back(x); } return c.clean(); } BigInteger operator * (const BigInteger& b) const { int i, j; LL g; vector<LL> v(s.size()+b.s.size(), 0); BigInteger c; c.s.clear(); for(i=0;i<s.size();i++) for(j=0;j<b.s.size();j++) v[i+j]+=LL(s[i])*b.s[j]; for (i = 0, g = 0; ; i++) { if (g ==0 && i >= v.size()) break; LL x = v[i] + g; c.s.push_back(x % BASE); g = x / BASE; } return c.clean(); } BigInteger operator / (const BigInteger& b) const { assert(b > 0); // ³ýÊý±ØÐë´óÓÚ0 BigInteger c = *this; // ÉÌ:Ö÷ÒªÊÇÈÃc.sºÍ(*this).sµÄvectorÒ»Ñù´ó BigInteger m; // ÓàÊý:³õʼ»¯Îª0 for (int i = s.size()-1; i >= 0; i--) { m = m*BASE + s[i]; c.s[i] = bsearch(b, m); m -= b*c.s[i]; } return c.clean(); } BigInteger operator % (const BigInteger& b) const { //·½·¨Óë³ý·¨Ïàͬ BigInteger c = *this; BigInteger m; for (int i = s.size()-1; i >= 0; i--) { m = m*BASE + s[i]; c.s[i] = bsearch(b, m); m -= b*c.s[i]; } return m; } // ¶þ·Ö·¨ÕÒ³öÂú×ãbx<=mµÄ×î´óµÄx int bsearch(const BigInteger& b, const BigInteger& m) const{ int L = 0, R = BASE-1, x; while (1) { x = (L+R)>>1; if (b*x<=m) {if (b*(x+1)>m) return x; else L = x;} else R = x; } } BigInteger& operator += (const BigInteger& b) {*this = *this + b; return *this;} BigInteger& operator -= (const BigInteger& b) {*this = *this - b; return *this;} BigInteger& operator *= (const BigInteger& b) {*this = *this * b; return *this;} BigInteger& operator /= (const BigInteger& b) {*this = *this / b; return *this;} BigInteger& operator %= (const BigInteger& b) {*this = *this % b; return *this;} bool operator < (const BigInteger& b) const { if (s.size() != b.s.size()) return s.size() < b.s.size(); for (int i = s.size()-1; i >= 0; i--) if (s[i] != b.s[i]) return s[i] < b.s[i]; return false; } bool operator >(const BigInteger& b) const{return b < *this;} bool operator<=(const BigInteger& b) const{return !(b < *this);} bool operator>=(const BigInteger& b) const{return !(*this < b);} bool operator!=(const BigInteger& b) const{return b < *this || *this < b;} bool operator==(const BigInteger& b) const{return !(b < *this) && !(b > *this);}};ostream& operator << (ostream& out, const BigInteger& x) { out << x.s.back(); for (int i = x.s.size()-2; i >= 0; i--) { char buf[20]; sprintf(buf, "%08d", x.s[i]); for (int j = 0; j < strlen(buf); j++) out << buf[j]; } return out;}istream& operator >> (istream& in, BigInteger& x) { string s; if (!(in >> s)) return in; x = s; return in;}BigInteger p2[410];#define MAXN (10000)int a[MAXN];void pre(int n){ Rep(i,n) a[i]=i;}bool vis[MAXN];BigInteger polya(int k,int *a,int n) { //Öû»²»¶¯µã¸öÊý Rep(i,n) vis[i]=0; int p=0; Rep(i,n) if (!vis[i]) { int j=i; do { vis[j]=1; j=a[j]; }while(!vis[j]); ++p; } return p2[p];}int a2[MAXN];int main(){ freopen("tickets.in","r",stdin); freopen("tickets.out","w",stdout); int n=read(),m=read(); pre(n*m); p2[1]=2; Fork(i,2,n*m) p2[i]=p2[i-1]*2; BigInteger ans=0; pre(n*m); Rep(i2,n) { Rep(j2,m) { Rep(i,n) Rep(j,m) a[i*m+j] = (i2+i)%n*m+(j+j2)%m; ans+=polya(2,a,n*m); if (n==m) { Rep(i,n) Rep(j,m) { a2[i*m+j] = a[(n-j-1)*m+i]; } ans+=polya(2,a2,n*m); } Rep(i,n) Rep(j,m) { a[(n-i-1)*m+(m-j-1)] = (i2+i)%n*m+(j+j2)%m; } ans+=polya(2,a,n*m); if (n==m) { Rep(i,n) Rep(j,m) { a2[i*m+j] = a[(n-j-1)*m+i]; } ans+=polya(2,a2,n*m); } } } ans/=(n*m*2); if (n==m) ans/=2; cout<<ans<<endl; return 0;}
阅读全文
0 0
- Andrew Stankevich Contest 2 (ASC 2) |我为什么要开这套题
- Andrew Stankevich's Contest #2 Solution
- ACdream Andrew Stankevich's Contest (2) 哈夫曼树
- Andrew Stankevich—2
- 【ACdream】1223 Roads Andrew Stankevich Contest 2 KM匹配
- Andrew Stankevich Contest
- 2004-2005 Summer Petrozavodsk Camp, Andrew Stankevich Contest 9 (ASC 9)
- Andrew Stankevich's Contest (1)
- Andrew Stankevich's Contest (21)
- Andrew Stankevich Contest 46 [Solo]
- Andrew Stankevich's Contest 23
- Andrew Stankevich Contest 28 - F
- Andrew Stankevich Contest 28 - I
- ZOJ 2313 Andrew Stankevich's Contest #1
- Andrew Stankevich's Contest #1 Solution
- Andrew Stankevich's Contest #8 Solution
- Andrew Stankevich's Contest #5 Solution
- Andrew Stankevich's Contest #10 Solution
- 陀螺仪数据处理
- casper.js
- 严蔚敏数据结构(C语言版)理解以及部分习题
- 【MVP】BaseActivity里面的内容
- maven中常用的依赖
- Andrew Stankevich Contest 2 (ASC 2) |我为什么要开这套题
- [js高手之路] dom常用节点属性兼容性详解与应用
- A
- 关于数据降维函数sklearn-PCA的使用
- HDU 6166 Senior Pan (最短路 好题)
- CodeForces
- python运维second_chapter(1)
- gcc 参数详解
- Hbase高级特性及其优化分析