NOIP提高组知识要点(搭建中)
来源:互联网 发布:淘宝天猫客服工作流程 编辑:程序博客网 时间:2024/06/05 05:55
基础
排序
- 快速排序
int main() { int a[]={3,4,5,6,23,4,5,7,100,1}; sort(a,a+10); return 0;}
- 归并排序
- 桶排序
- 基数排序
贪心
这个没什么好说的吧。。
分治
- 最近平面点对
// poj3714#include<algorithm>#include<iostream>#include<cstring>#include<cstdlib>#include<cstdio>#include<cmath>#include<vector>#define inf 2147483640#define LL long long#define free(a) freopen(a".in","r",stdin);freopen(a".out","w",stdout); usingnamespace std; inline LL getint() { LL x=0,f=1;char ch=getchar(); while (ch>'9' || ch<'0') {if (ch=='-') f=-1;ch=getchar();} while (ch>='0' && ch<='9') {x=x*10+ch-'0';ch=getchar();} return x*f;}const int maxn=1000010; struct point {double x,y;int flag;}p[maxn];int n,tmp[maxn];bool cmpx(point a,point b) { return a.x==b.x ? a.y<b.y : a.x<b.x;}bool cmpy(int a,int b) { return p[a].y==p[b].y ? p[a].x<p[b].x : p[a].y<p[b].y;}double dis(point a,point b) { return sqrt((double)(a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));}double solve(int l,int r) { double res=1e60; if (l==r) return res; if (l+1==r) { if (p[l].flag==p[r].flag) return res; return dis(p[l],p[r]); } int mid=(l+r)>>1; res=solve(l,mid); res=min(res,solve(mid+1,r)); int num=0; for (int i=l;i<=r;i++) if (fabs(p[i].x-p[mid].x)<=res) tmp[++num]=i; sort(tmp+1,tmp+num+1,cmpy); for (int i=1;i<=num;i++) for (int j=i+1;j<=num;j++) { if (fabs(p[tmp[i]].y-p[tmp[j]].y)>=res) break; //剪枝 if (p[tmp[i]].flag!=p[tmp[j]].flag) res=min(res,dis(p[tmp[i]],p[tmp[j]])); } return res;}int main() { int T; scanf("%d",&T); while (T--) { scanf("%d",&n); for (int i=1;i<=n;i++) scanf("%lf%lf",&p[i].x,&p[i].y),p[i].flag=0; for (int i=1;i<=n;i++) scanf("%lf%lf",&p[i+n].x,&p[i+n].y),p[i+n].flag=1; n<<=1; sort(p+1,p+1+n,cmpx); printf("%.3f\n",solve(1,n)); } return 0; }
- 归并排序求逆序对
// poj1804#include<algorithm>#include<iostream>#include<cstdlib>#include<cstring>#include<cstdio>#include<cmath>#define LL long long#define inf 2147483640#define Pi acos(-1.0)#define free(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout);using namespace std;inline LL getint() { int f,x=0;char ch=getchar(); while (ch<='0' || ch>'9') {if (ch=='-') f=-1;else f=1;ch=getchar();} while (ch>='0' && ch<='9') {x=x*10+ch-'0';ch=getchar();} return x*f;}const int maxn=1010;int a[maxn],tmp[maxn],ans,n;void solve(int l,int r) { if (l<r) { int mid=(l+r)>>1; solve(l,mid); solve(mid+1,r); int i=l,j=mid+1,k=l; while (i<=mid && j<=r) { if (a[i]>a[j]) {tmp[k++]=a[j++];ans+=mid-i+1;} else tmp[k++]=a[i++]; } while (i<=mid) tmp[k++]=a[i++]; while (j<=r) tmp[k++]=a[j++]; for (int i=l;i<=r;i++) a[i]=tmp[i]; }}int main() { int T,tt=0;scanf("%d",&T); while (T--) { scanf("%d",&n); for (int i=1;i<=n;i++) scanf("%d",&a[i]); ans=0; solve(1,n); printf("Scenario #%d:\n%d\n\n",++tt,ans); } return 0;}
二分
- Pie
// poj3122#include<algorithm>#include<iostream>#include<cstdlib>#include<cstring>#include<cstdio>#include<cmath>#define LL long long#define inf 2147483640#define Pi acos(-1.0)#define free(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout);using namespace std;int n,f,r[1000010];double a[1000010];bool ok(double m) { int sum=0; for (int i=1;i<=n;i++) sum+=floor(a[i]/m); return sum>=f+1;}int main() { int T; scanf("%d",&T); while (T--) { scanf("%d%d",&n,&f); double maxl=-1; for (int i=1;i<=n;i++) { scanf("%d",&r[i]),a[i]=r[i]*r[i]*Pi; maxl=max(maxl,a[i]); } double l=0.0,r=maxl; while (r-l>1e-5) { double mid=(l+r)/2; if (ok(mid)) l=mid; else r=mid; } printf("%.4lf\n",l); } return 0;}
三分
- 传送带
// bzoj1857#include<algorithm>#include<iostream>#include<cstring>#include<cstdlib>#include<cstdio>#include<cmath>#include<set>#define eps 1e-9#define inf 2147483640#define LL long long#define free(a) freopen(a".in","r",stdin);freopen(a".out","w",stdout);using namespace std;inline LL getint() { LL x=0,f=1;char ch=getchar(); while (ch>'9' || ch<'0') {if (ch=='-') f=-1;ch=getchar();} while (ch>='0' && ch<='9') {x=x*10+ch-'0';ch=getchar();} return x*f;}int ax,bx,cx,dx,ay,by,cy,dy,p,q,r;double dis(double x1,double y1,double x2,double y2) { return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));}double cal(double x,double y) { double x1,y1,x2,y2,t1,t2; double lx=cx,ly=cy,rx=dx,ry=dy; while (fabs(lx-rx)>eps || fabs(ly-ry)>eps) { x1=lx+(rx-lx)/3;x2=lx+(rx-lx)/3*2; y1=ly+(ry-ly)/3;y2=ly+(ry-ly)/3*2; t1=dis(ax,ay,x,y)/p+dis(x,y,x1,y1)/r+dis(x1,y1,dx,dy)/q; t2=dis(ax,ay,x,y)/p+dis(x,y,x2,y2)/r+dis(x2,y2,dx,dy)/q; if (t1>t2) lx=x1,ly=y1; else rx=x2,ry=y2; } //return min(t1,t2); return dis(ax,ay,x,y)/p+dis(x,y,lx,ly)/r+dis(lx,ly,dx,dy)/q;}int main() { scanf("%d%d%d%d",&ax,&ay,&bx,&by); scanf("%d%d%d%d",&cx,&cy,&dx,&dy); scanf("%d%d%d",&p,&q,&r); double x1,x2,y1,y2,t1,t2; double lx=ax,ly=ay,rx=bx,ry=by; while (fabs(rx-lx)>eps || fabs(ry-ly)>eps) { x1=lx+(rx-lx)/3;x2=lx+(rx-lx)/3*2; y1=ly+(ry-ly)/3;y2=ly+(ry-ly)/3*2; t1=cal(x1,y1);t2=cal(x2,y2); if (t1>t2) lx=x1,ly=y1; else rx=x2,ry=y2; } printf("%.2f",cal(lx,ly)); //printf("%.2f",min(t1,t2)); return 0;}
高精度
- 高精度+高精度
// codevs3116#include<algorithm>#include<iostream>#include<cstdlib>#include<cstring>#include<cstdio>#include<cmath>#define LL long long#define inf 2147483640#define MOD 31011#define Pi acos(-1.0)#define free(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout);using namespace std;int getint() { int f=1,x=0;char ch=getchar(); while (ch<='0' || ch>'9') {if (ch=='-') f=-1;ch=getchar();} while (ch>='0' && ch<='9') {x=x*10+ch-'0';ch=getchar();} return x*f;}const int maxn=1010;char s1[maxn],s2[maxn];int a[maxn],b[maxn];int jia(char *s1,char *s2) { int k; for (int i=0;i<(k=strlen(s1));i++) a[k-i]=s1[i]-'0'; for (int i=0;i<(k=strlen(s2));i++) b[k-i]=s2[i]-'0'; k=max(strlen(s1),strlen(s2)); for (int i=1;i<=k;i++) { a[i]+=b[i]; a[i+1]+=a[i]/10; a[i]%=10; } while (a[k+1]>0) k++; return k;}int main() { scanf("%s%s",s1,s2); int k=jia(s1,s2); for (int i=k;i>=1;i--) printf("%d",a[i]); return 0;}
- 高精度-高精度
// codevs3115#include<algorithm>#include<iostream>#include<cstdlib>#include<cstring>#include<cstdio>#include<cmath>#define LL long long#define inf 2147483640#define MOD 31011#define Pi acos(-1.0)#define free(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout);using namespace std;int getint() { int f=1,x=0;char ch=getchar(); while (ch<='0' || ch>'9') {if (ch=='-') f=-1;ch=getchar();} while (ch>='0' && ch<='9') {x=x*10+ch-'0';ch=getchar();} return x*f;}const int maxn=1010;char s1[maxn],s2[maxn];int a[maxn],b[maxn];int jian(char *s1,char *s2) { int k; if (strlen(s1)<strlen(s2) || (strlen(s1)==strlen(s2) && s1<s2)) {swap(s1,s2);printf("-");} for (int i=0;i<(k=strlen(s1));i++) a[k-i]=s1[i]-'0'; for (int i=0;i<(k=strlen(s2));i++) b[k-i]=s2[i]-'0'; k=strlen(s1); for (int i=1;i<=k;i++) { a[i]-=b[i]; if (a[i]<0) a[i]+=10,a[i+1]--; } while (a[k]==0) k--; return k;}int main() { scanf("%s%s",s1,s2); int k=jian(s1,s2); for (int i=k;i>=1;i--) printf("%d",a[i]); return 0;}
- 高精度×高精度
// codevs3117#include<algorithm>#include<iostream>#include<cstdlib>#include<cstring>#include<cstdio>#include<cmath>#define LL long long#define inf 2147483640#define MOD 31011#define Pi acos(-1.0)#define free(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout);using namespace std;int getint() { int f=1,x=0;char ch=getchar(); while (ch<='0' || ch>'9') {if (ch=='-') f=-1;ch=getchar();} while (ch>='0' && ch<='9') {x=x*10+ch-'0';ch=getchar();} return x*f;}const int maxn=1010;char s1[maxn],s2[maxn];int a[maxn],b[maxn],c[maxn*maxn];int cheng(char *s1,char *s2) { int k1,k2; for (int i=0;i<(k1=strlen(s1));i++) a[k1-i]=s1[i]-'0'; for (int i=0;i<(k2=strlen(s2));i++) b[k2-i]=s2[i]-'0'; int cnt=k1+k2+1; for (int i=1;i<=k1;i++) { for (int j=1;j<=k2;j++) { c[i+j-1]+=a[i]*b[j]; c[i+j]+=c[i+j-1]/10; c[i+j-1]%=10; } for (int j=i+k2;c[j]>=10;j++) { c[j+1]+=c[j]/10; c[j]%=10; } } while (c[cnt]==0) cnt--; return cnt;}int main() { scanf("%s%s",s1,s2); int k=cheng(s1,s2); for (int i=k;i>=1;i--) printf("%d",c[i]); return 0;}
- 高精度÷高精度(没怎么写过,套了个减法,奇丑无比= =)
// codevs3118#include<algorithm>#include<iostream>#include<cstdlib>#include<cstring>#include<cstdio>#include<cmath>#include<string>#define LL long long#define inf 2147483640#define MOD 31011#define Pi acos(-1.0)#define free(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout);using namespace std;int getint() { int f=1,x=0;char ch=getchar(); while (ch<='0' || ch>'9') {if (ch=='-') f=-1;ch=getchar();} while (ch>='0' && ch<='9') {x=x*10+ch-'0';ch=getchar();} return x*f;}const int maxn=1010;char s1[maxn],s2[maxn];int a[maxn],b[maxn],c[maxn*maxn],d[maxn];string s;bool cmp(int kk) { for (int i=kk;i>=1;i--) { if (c[i]<b[i]) return 1; else if (c[i]>b[i]) return 0; } return 0;}int jian(int k) { int kk=s.length(); for (int i=0;i<kk;i++) c[kk-i]=s[i]-'0'; if (kk<k || (kk==k && cmp(kk))) return 0; s.clear(); for (int i=1;i<=k;i++) { c[i]-=b[i]; if (c[i]<0) c[i]+=10,c[i+1]--; } while (c[kk]==0) kk--; for (int i=kk;i>=1;i--) s+=c[i]+'0'; return 1;}int chu() { int k1,k2,cnt; for (int i=0;i<(k1=strlen(s1));i++) a[i+1]=s1[i]-'0'; for (int i=0;i<(k2=strlen(s2));i++) b[k2-i]=s2[i]-'0'; if (k1<k2 || (k1==k2 && s1<s2)) return 0; cnt=k1; for (int i=1;i<=k1;i++) { s+=(char)(a[i]+'0'); while (jian(k2)==1) d[k1-i+1]++; } while (d[cnt]==0) cnt--; return cnt;}int main() { scanf("%s%s",s1,s2); int k=chu(); for (int i=k;i>=1;i--) printf("%d",d[i]); return 0;}
数学
最大公约数与最小公倍数
- gcd
// codevs1212#include<algorithm>#include<iostream>#include<cstring>#include<cstdlib>#include<cstdio>#include<cmath>#include<set>#define MOD 1000000007#define inf 2147483640#define LL long long#define free(a) freopen(a".in","r",stdin);freopen(a".out","w",stdout);using namespace std;int gcd(int a,int b) { return b==0 ? a : gcd(b,a%b);}int main() { int a,b; scanf("%d%d",&a,&b); printf("%d",gcd(a,b)); return 0;}
- lcm
// codevs1459#include<algorithm>#include<iostream>#include<cstring>#include<cstdlib>#include<cstdio>#include<cmath>#include<set>#define MOD 1000000007#define inf 2147483640#define LL long long#define free(a) freopen(a".in","r",stdin);freopen(a".out","w",stdout);using namespace std;int gcd(int a,int b) { return b==0 ? a : gcd(b,a%b);}int main() { int n,ans; scanf("%d",&n); scanf("%d",&ans); for (int x,i=1;i<=n;i++) { scanf("%d",&x); ans=ans*x/gcd(ans,x); } printf("%d",ans); return 0;}
快速幂
- 快速幂
// codevs3500#include<algorithm>#include<iostream>#include<cstdlib>#include<cstring>#include<cstdio>#include<cmath>#include<string>#define LL long long#define inf 2147483640#define MOD 31011#define Pi acos(-1.0)#define free(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout);using namespace std;int getint() { int f=1,x=0;char ch=getchar(); while (ch<='0' || ch>'9') {if (ch=='-') f=-1;ch=getchar();} while (ch>='0' && ch<='9') {x=x*10+ch-'0';ch=getchar();} return x*f;}LL pow(LL a,LL b,LL c) { LL ans=1; while (b) { if (b&1) ans=(ans*a)%c; b/=2;a=(a*a)%c; } return ans;}int main() { LL a,b,c; scanf("%lld%lld%lld",&a,&b,&c); printf("%lld",power(a,b,c)); return 0;}
乘法逆元
- 扩展欧几里得算法
// codevs1200#include<algorithm>#include<iostream>#include<cstdlib>#include<cstring>#include<cstdio>#include<cmath>#define LL long long#define inf 2147483640#define Pi 3.1415926535898#define free(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout);using namespace std;void exgcd(LL a,LL b,LL &x,LL &y) { if (b==0) {x=1;y=0;return;} exgcd(b,a%b,y,x); y-=(a/b)*x;}int main() { LL x,y,a,b; scanf("%lld%lld",&a,&b); exgcd(a,b,x,y); printf("%lld",(x%b+b)%b); //x可能为负数 return 0;}
中国剩余定理
- 求解模线性方程一般情况(模数不互质)
// poj2891#include<algorithm>#include<iostream>#include<cstdlib>#include<cstring>#include<cstdio>#include<cmath>#define LL long long#define inf 2147483640#define Pi 3.1415926535898#define free(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout);using namespace std;const int maxn=100010;LL mm[maxn],rr[maxn],n;LL gcd(LL a,LL b) { return b==0 ? a : gcd(b,a%b);}void exgcd(LL a,LL b,LL &x,LL &y) { if (!b) {x=1,y=0;return;} exgcd(b,a%b,y,x); y-=x*(a/b); //注意此处a/b一定要到打括号,因为取的是a/b的整数部分}int main() { while (scanf("%lld",&n)!=EOF) { LL M,R,flag=1; scanf("%lld%lld",&M,&R); for (int i=1;i<n;i++) scanf("%lld%lld",&mm[i],&rr[i]); for (int i=1;i<n;i++) { LL m,r,x,y; m=mm[i],r=rr[i]; LL d=gcd(M,m); if ((r-R)%d!=0) {printf("-1\n");flag=0;break;} exgcd(M/d,m/d,x,y); //x*(M/d)+y*(m/d)=d,解出x,y x=((r-R)/d*x%(m/d)+(m/d))%(m/d); //求出最小x R+=M*x; M*=m/d; //lcm(M,m) } if (flag) printf("%lld\n",R); } return 0;}
博弈论
- 猜想,推理与证明
// poj1740#include<algorithm>#include<iostream>#include<cstring>#include<cstdlib>#include<cstdio>#include<cmath>#include<map>#define inf 2147483640#define LL long long#define free(a) freopen(a".in","r",stdin);freopen(a".out","w",stdout);using namespace std;inline LL getint() { LL x=0,f=1;char ch=getchar(); while (ch>'9' || ch<'0') {if (ch=='-') f=-1;ch=getchar();} while (ch>='0' && ch<='9') {x=x*10+ch-'0';ch=getchar();} return x*f;}int n,a[1010];int main() { while (scanf("%d",&n)!=EOF && n) { for (int i=1;i<=n;i++) scanf("%d",&a[i]); sort(a+1,a+1+n); if (n%2==0) { int flag=1; for (int i=2;i<=n;i+=2) if (a[i]!=a[i-1]) {flag=0;break;} if (flag) {printf("0\n");continue;} } printf("1\n"); } return 0;}
- 威佐夫博奕(Wythoff Game)
// poj1067#include<algorithm>#include<iostream>#include<cstring>#include<cstdlib>#include<cstdio>#include<cmath>#include<map>#define esp 1e-8#define inf 2147483640#define LL long long#define Pi acos(-1.0)#define free(a) freopen(a".in","r",stdin);freopen(a".out","w",stdout);using namespace std;inline LL getint() { LL x=0,f=1;char ch=getchar(); while (ch>'9' || ch<'0') {if (ch=='-') f=-1;ch=getchar();} while (ch>='0' && ch<='9') {x=x*10+ch-'0';ch=getchar();} return x*f;}int main() { int a,b; double i=pow(5,0.5); while (scanf("%d%d",&a,&b)!=EOF) { if (a>b) swap(a,b); int k=(double)a*(i-1.0)/2.0; int s=k*(1+i)/2; if (s==a && a+k==b) printf("0\n"); else { k++; s=k*(1+i)/2; if (s==a && a+k==b) printf("0\n"); else printf("1\n"); } } return 0;}
- 取石子游戏
// poj2960#include<algorithm>#include<iostream>#include<cstring>#include<cstdlib>#include<cstdio>#include<cmath>#include<map>#define inf 2147483640#define LL long long#define free(a) freopen(a".in","r",stdin);freopen(a".out","w",stdout);using namespace std;inline LL getint() { LL x=0,f=1;char ch=getchar(); while (ch>'9' || ch<'0') {if (ch=='-') f=-1;ch=getchar();} while (ch>='0' && ch<='9') {x=x*10+ch-'0';ch=getchar();} return x*f;}int main() { int n; while (scanf("%d",&n)!=EOF) { int ans=0; for (int i=1;i<=n;i++) { int x; scanf("%d",&x); ans^=x; } if (ans) printf("Yes\n"); else printf("No\n"); } return 0;}
- 暴力求解SG(打表找规律)
// poj2960#include<algorithm>#include<iostream>#include<cstring>#include<cstdlib>#include<cstdio>#include<cmath>#include<map>#define inf 2147483640#define LL long long#define free(a) freopen(a".in","r",stdin);freopen(a".out","w",stdout);using namespace std;inline LL getint() { LL x=0,f=1;char ch=getchar(); while (ch>'9' || ch<'0') {if (ch=='-') f=-1;ch=getchar();} while (ch>='0' && ch<='9') {x=x*10+ch-'0';ch=getchar();} return x*f;}const int maxn=10010;int k,n,m,sg[maxn],s[maxn];void calsg(int x) { if (sg[x]!=-1) return; //map<int,bool> mark; bool mark[10010]; memset(mark,0,sizeof(mark)); int temp; for (int i=1;i<=k;i++) { temp=x-s[i]; if (temp>=0) { if (sg[temp]==-1) calsg(temp); mark[sg[temp]]=1; } } for (int i=0;;i++) if (!mark[i]) {sg[x]=i;return;}}int main() { while (scanf("%d",&k)!=EOF && k) { for (int i=1;i<=k;i++) scanf("%d",&s[i]); sg[0]=0; for (int i=1;i<=maxn;i++) sg[i]=-1; scanf("%d",&m); while (m--) { scanf("%d",&n); int ans=0; while (n--) { int x;scanf("%d",&x); if (sg[x]==-1) calsg(x); ans^=sg[x]; } if (ans) printf("W"); else printf("L"); } printf("\n"); } return 0;}
容斥原理
- dfs求解
// bzoj1853#include<algorithm>#include<iostream>#include<cstring>#include<cstdlib>#include<cstdio>#include<cmath>#include<map>#define inf 2147483640#define LL long long#define free(a) freopen(a".in","r",stdin);freopen(a".out","w",stdout);using namespace std;inline LL getint() { LL x=0,f=1;char ch=getchar(); while (ch>'9' || ch<'0') {if (ch=='-') f=-1;ch=getchar();} while (ch>='0' && ch<='9') {x=x*10+ch-'0';ch=getchar();} return x*f;}int n,m,vis[100010];LL l,r,ans,a[100010],b[100010];void pre(int x,LL y) { if (y>r)return; if (x>0) a[++m]=y; pre(x+1,y*10+6); pre(x+1,y*10+8);}LL gcd(LL x,LL y) { return x%y==0?y:gcd(y,x%y);}void dfs(int x,int y,LL z) { if (x>n) { if (y&1) ans+=r/z-(l-1)/z; else if (y) ans-=r/z-(l-1)/z; return; } dfs(x+1,y,z); LL tmp=z/gcd(a[x],z); if ((double)a[x]*tmp<=r) dfs(x+1,y+1,a[x]*tmp);}int main() { scanf("%lld%lld",&l,&r); pre(0,0); sort(a+1,a+1+m); memset(vis,0,sizeof(vis)); for (int i=1;i<=m;i++) if (!vis[i]) { for (int j=i+1;j<=m;j++) if (a[j]%a[i]==0) vis[j]=1; b[++n]=a[i]; } for (int i=1;i<=n;i++) a[n-i+1]=b[i]; dfs(1,0,1); printf("%lld",ans); return 0;}
高斯消元
- 求解n元1次方程组
// bzoj1013#include<algorithm>#include<iostream>#include<cstdlib>#include<cstring>#include<cstdio>#include<cmath>#define LL long long#define inf 2147483640#define eps 1e-7#define Pi 3.1415926535898#define free(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout);using namespace std;const int maxn=30;double ans[maxn],f[maxn],a[maxn][maxn];int n;double sqr(double x) { return x*x;}void Gauss() { for (int i=1;i<=n;i++) { int x=i; while (x<=n && fabs(a[x][i])<=eps) x++; if (x>n) continue; swap(a[x],a[i]); for (int j=i+1;j<=n;j++) { double t=a[i][i]/a[j][i]; for (int k=1;k<=n+1;k++) a[j][k]=a[j][k]*t-a[i][k]; } } for (int i=n;i>=1;i--) { double t=a[i][n+1]; for (int j=i+1;j<=n;j++) t-=ans[j]*a[i][j]; ans[i]=t/a[i][i]; }} int main() { scanf("%d",&n); for (int i=1;i<=n;i++) scanf("%lf",&f[i]); for (int i=1;i<=n;i++) for (int j=1;j<=n;j++) { double t; scanf("%lf",&t); a[i][j]=2*(t-f[j]); a[i][n+1]+=sqr(t)-sqr(f[j]); } Gauss(); for (int i=1;i<n;i++) printf("%.3lf ",ans[i]); printf("%.3lf",ans[n]); return 0;}
- 静态线性基
// bzoj2115#include<algorithm>#include<iostream>#include<cstdlib>#include<cstring>#include<cstdio>#include<cmath>#define LL long long#define inf 2147483640#define Pi 3.1415926535898#define free(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout);using namespace std;const int maxn=50010,maxm=100010;struct edge {int to,next;LL w;}e[maxm<<1];LL dis[maxn],c[maxm<<2],bin[65];int vis[maxn],n,m,tot,sum,cnt,head[maxn];void link(int u,int v,LL w) { e[++cnt].to=v;e[cnt].next=head[u];head[u]=cnt;e[cnt].w=w; e[++cnt].to=u;e[cnt].next=head[v];head[v]=cnt;e[cnt].w=w;}void dfs(int x) { vis[x]=1; for (int i=head[x];i;i=e[i].next) { if (!vis[e[i].to]) { dis[e[i].to]=dis[x]^e[i].w; dfs(e[i].to); } else c[++sum]=dis[x]^dis[e[i].to]^e[i].w; }}void Gauss() { for (LL i=bin[60];i;i>>=1) { int j=tot+1; while (j<=sum && !(c[j]&i)) j++; if (j==sum+1) continue; swap(c[++tot],c[j]); for (j=1;j<=sum;j++) if (j!=tot && c[j]&i) c[j]^=c[tot]; }}int main() { bin[0]=1;for (int i=1;i<=60;i++) bin[i]=bin[i-1]<<1; scanf("%d%d",&n,&m); for (int u,v,i=1;i<=m;i++) { LL w; scanf("%d%d%lld",&u,&v,&w); link(u,v,w); } dfs(1); Gauss(); LL ans=dis[n]; for (int i=1;i<=tot;i++) ans=max(ans,ans^c[i]); printf("%lld\n",ans); return 0;}
矩阵乘法
- 递推优化
// poj3070#include<algorithm>#include<iostream>#include<cstdlib>#include<cstring>#include<cstdio>#include<cmath>#define LL long long#define inf 2147483640#define Pi acos(-1.0)#define free(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout);using namespace std;int n,a[2][2],b[2][2];void mul(int a[2][2],int b[2][2],int ans[2][2]) { int t[2][2]; for (int i=0;i<2;i++) for (int j=0;j<2;j++) { t[i][j]=0; for (int k=0;k<2;k++) t[i][j]=(t[i][j]+a[i][k]*b[k][j])%10000; } for (int i=0;i<2;i++) for (int j=0;j<2;j++) ans[i][j]=t[i][j];}void pow(int k) { while (k) { if (k&1) mul(a,b,b); k>>=1; mul(a,a,a); }}int main() { while (scanf("%d",&n)!=EOF) { if (n==-1) break; a[0][0]=a[0][1]=a[1][0]=1;a[1][1]=0; b[0][0]=b[1][1]=1; b[1][0]=b[0][1]=0; pow(n); printf("%d\n",b[1][0]); } return 0;}
搜索
迭代加深
- 埃及分数
// codevs3500#include<algorithm>#include<iostream>#include<cstdlib>#include<cstring>#include<cstdio>#include<cmath>#include<string>#define LL long long#define inf 2147483640#define MOD 31011#define Pi acos(-1.0)#define free(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout);using namespace std;int getint() { int f=1,x=0;char ch=getchar(); while (ch<='0' || ch>'9') {if (ch=='-') f=-1;ch=getchar();} while (ch>='0' && ch<='9') {x=x*10+ch-'0';ch=getchar();} return x*f;}const int maxn=10010;LL t[maxn],ans[maxn];int d;LL gcd(LL a,LL b) { return a%b==0 ? b : gcd(b,a%b);}int dfs(LL a,LL b,int x) { int flag=0; if (x==d+1) return 0; if (b%a==0 && b/a>t[x-1]) { t[x]=b/a; if (ans[d]>t[x] || ans[d]==0) for (int i=1;i<=d;i++) ans[i]=t[i]; return 1; } LL l=max(b%a==0 ? b/a : b/a+1,t[x-1]+1),r=(d-x+1)*(b/a); for (LL i=l;i<=r;i++) { t[x]=i; if (i==14955) { i=i; t[x]=i; } int tmp=gcd(a*i-b,b*i); if (dfs((a*i-b)/tmp,(b*i)/tmp,x+1)) flag=1; } return flag;} int main() { int a,b; scanf("%d%d",&a,&b); int x=gcd(a,b); a/=x;b/=x; for (d=1;d;d++) if (dfs(a,b,1)) { for (int i=1;i<=d;i++) printf("%lld ",ans[i]); break; } return 0;}
meet in the middle
- 方程的解数
// poj1186#include<algorithm>#include<iostream>#include<cstdlib>#include<cstring>#include<cstdio>#include<cmath>#define MOD 10000007#define LL long long#define inf 2147483640#define Pi 3.1415926535898#define free(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout);using namespace std;struct hash {int w,next,num;}h[100000010];int cnt,ans,n,m,head[MOD],p[10],k[10],pd[1010][1010];void dfs1(int x,int w) { if (x>n/2) { int i=abs(w)%MOD; bool flag=1; for (int j=head[i];j;j=h[j].next) if (w==h[j].w) {h[j].num++;flag=0;break;} if (flag) {h[++cnt].w=w;h[cnt].next=head[i];head[i]=cnt;h[cnt].num++;} } else for (int i=1;i<=m;i++) dfs1(x+1,w+k[x]*pd[i][p[x]]);}void dfs2(int x,int w) { if (x>n) { int i=abs(w)%MOD; for (int j=head[i];j;j=h[j].next) if (-w==h[j].w) {ans+=h[j].num;break;} } else for (int i=1;i<=m;i++) dfs2(x+1,w+k[x]*pd[i][p[x]]);}int main() { scanf("%d%d",&n,&m); for (int i=0;i<=m;i++) { pd[i][0]=1; for (int j=1;j<=m;j++) pd[i][j]=pd[i][j-1]*i; } for (int i=1;i<=n;i++) scanf("%d%d",&k[i],&p[i]); dfs1(1,0); dfs2(n/2+1,0); printf("%d",ans); return 0;}
dfs+剪枝
- stick
// poj 1011#include<algorithm>#include<iostream>#include<cstdlib>#include<cstring>#include<cstdio>#include<cmath>#define LL long long#define inf 2147483640#define Pi 3.1415926535898#define free(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout);using namespace std;int n,m,ans,length,a[100010],times,sum;bool b[100010],flag;void fit(int x);void dfs(int x,int len,int lev) { if (len==length) {fit(x+1);return;} for (int i=lev+1;i<=n;i++) if (!b[i] && len+a[i]<=length) { if (n-times+1<ans-x) return; b[i]=1; times++; dfs(x,len+a[i],i); times--; b[i]=0; int j=i; if (flag) return; while (i<n && a[i]==a[j]) i++; if (i==n) return; if (i!=j) i--; }}void fit(int x) { int t; if (x>=ans) {flag=1;return;} for (int i=1;i<=n;i++) if (!b[i]) {t=i;break;} b[t]=1; times++; dfs(x,a[t],t); times--; b[t]=0;}bool cmp(int a,int b) {return a>b;}int main() { while (scanf("%d",&n)==1) { if (n==0) break; sum=0;int maxl=0; for (int i=1;i<=n;i++) { scanf("%d",&a[i]); maxl=max(maxl,a[i]); sum+=a[i]; } sort(a+1,a+1+n,cmp); memset(b,0,sizeof(b)); for (int i=n;i>=1;i--) { ans=i;length=sum/i; if (i==1) break; if (sum%i>0 || length<maxl) continue; memset(b,0,sizeof(b)); times=0; flag=0; fit(1); if (flag) break; } printf("%d\n",sum/ans); } return 0;}
bfs
- 八数码
// codevs1225#include<algorithm>#include<iostream>#include<cstdlib>#include<cstring>#include<cstdio>#include<cmath>#include<string>#define LL long long#define inf 2147483640#define Pi acos(-1.0)#define free(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout);using namespace std;int getint() { int f=1,x=0;char ch=getchar(); while (ch<='0' || ch>'9') {if (ch=='-') f=-1;ch=getchar();} while (ch>='0' && ch<='9') {x=x*10+ch-'0';ch=getchar();} return x*f;}int b[1000001],head,tail;char a[1000001][11];bool f[1000001][5];int find() { int k,i; k=strlen(a[head]); for (i=0;i<=k-1;i++) if ((a[head][i]=='0')) break; return i;}bool check(char *a) { if (strcmp(a,"123804765")==0) return 1; else return 0;}void search() { int p; char t,s[11]; head=0;tail=1; b[1]=0; memset(s,0,sizeof(s)); do { head++; p=find(); if (p%3!=0&&f[head][1]) { //right strcpy(s,a[head]); t=s[p];s[p]=s[p-1];s[p-1]=t; tail++; strcpy(a[tail],s); b[tail]=b[head]+1; f[tail][3]=0; if (check(a[tail])) {head=tail;break;} } if (p>=3&&f[head][2]) { //up strcpy(s,a[head]); t=s[p];s[p]=s[p-3];s[p-3]=t; tail++; strcpy(a[tail],s); b[tail]=b[head]+1; f[tail][4]=0; if (check(a[tail])) {head=tail;break;} } if ((p+1)%3!=0&&f[head][3]) { //left strcpy(s,a[head]); t=s[p];s[p]=s[p+1];s[p+1]=t; tail++; strcpy(a[tail],s); b[tail]=b[head]+1; f[tail][1]=0; if (check(a[tail])) {head=tail;break;} } if (p<=5&&f[head][4]) { //down strcpy(s,a[head]); t=s[p];s[p]=s[p+3];s[p+3]=t; tail++; strcpy(a[tail],s); b[tail]=b[head]+1; f[tail][2]=0; if (check(a[tail])) {head=tail;break;} } }while (head<tail);}int main() { scanf("%s",a[1]); memset(f,1,sizeof(f)); search(); printf("%d",b[tail]); return 0;}
dfs序
- apple tree
图论
并查集
- 路径压缩
// codevs1225#include<algorithm>#include<iostream>#include<cstdlib>#include<cstring>#include<cstdio>#include<cmath>#include<string>#define LL long long#define inf 2147483640#define Pi acos(-1.0)using namespace std;int getint() { int f=1,x=0;char ch=getchar(); while (ch<='0' || ch>'9') {if (ch=='-') f=-1;ch=getchar();} while (ch>='0' && ch<='9') {x=x*10+ch-'0';ch=getchar();} return x*f;}int m,n,p,fa[100001];int find(int x) { return x==fa[x] ? x : fa[x]=find(fa[x]);}int main() { scanf("%d%d%d",&n,&m,&p); for (int i=1;i<=n;i++) fa[i]=i; for (int i=1,x,y;i<=m;i++) { scanf("%d%d",&x,&y); int r1=find(x),r2=find(y); if (r1!=r2) fa[r1]=r2; } for (int i=1,x,y;i<=p;i++) { scanf("%d%d",&x,&y); int r1=find(x),r2=find(y); if (r1==r2) printf("Yes\n"); else printf("No\n"); } return 0;}
- 带权并查集
// poj1182#include<algorithm>#include<iostream>#include<cstdlib>#include<cstring>#include<cstdio>#include<cmath>#define LL long long#define inf 2147483640#define Pi 3.1415926535898#define free(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout);using namespace std;int fa[1000010],r[1000010],n,k;int find(int x) { if (x!=fa[x]) { int fx=find(fa[x]); r[x]=(r[x]+r[fa[x]])%3; fa[x]=fx; } return fa[x];}bool Union(int x,int y,int type) { int fx,fy; fx=find(x);fy=find(y); if (fx==fy) { if ((r[y]-r[x]+3)%3!=type) return 1; else return 0; } fa[fy]=fx; r[fy]=(r[x]-r[y]+type+3)%3; return 0;}int main() { scanf("%d%d",&n,&k); for (int i=1;i<=n;i++) fa[i]=i; memset(r,0,sizeof(r)); int sum=0; while (k--) { int d,x,y; scanf("%d%d%d",&d,&x,&y); if (x>n || y>n || (x==y && d==2)) sum++; else if (Union(x,y,d-1)) sum++; } printf("%d",sum); return 0;}
最短路
- floyed(n³)
// codevs2602#include<algorithm>#include<iostream>#include<cstring>#include<cstdlib>#include<cstdio>#include<cmath>#include<set>#define MOD 1000000007#define inf 2147483640#define LL long long#define free(a) freopen(a".in","r",stdin);freopen(a".out","w",stdout);using namespace std;int n,m,i,j,k,s,e;double f[1001][1001],a[1001][1001];int main() { scanf("%d",&n); for (i=1;i<=n;i++) scanf("%lf%lf",&a[i][1],&a[i][2]); memset(f,0x7f,sizeof(f)); scanf("%d",&m); for (i=1;i<=m;i++) { scanf("%d%d",&j,&k); f[j][k]=f[k][j]=sqrt(pow(a[j][1]-a[k][1],2)+pow(a[j][2]-a[k][2],2)); } scanf("%d%d",&s,&e); for (k=1;k<=n;k++) for (i=1;i<=n;i++) for (j=1;j<=n;j++) if ((i!=j)&&(i!=k)&&(j!=k)&&(f[i][j]>f[i][k]+f[j][k])) f[i][j]=f[i][k]+f[j][k]; printf("%.2f",f[s][e]); return 0;}
- dijkstra+堆(nlogn):不能处理负边权以及最长路
// poj3159#include<algorithm>#include<iostream>#include<cstdlib>#include<cstring>#include<cstdio>#include<cmath>#include<queue>#define LL long long#define inf 2147483640#define MOD 998244353#define Pi acos(-1.0)#define free(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout);using namespace std;inline LL getint() { int f,x=0;char ch=getchar(); while (ch<='0' || ch>'9') {if (ch=='-') f=-1;else f=1;ch=getchar();} while (ch>='0' && ch<='9') {x=x*10+ch-'0';ch=getchar();} return x*f;}const int maxn=30010,maxm=150010;struct edge {int to,next,w;}e[maxm];struct data { int x,num; friend bool operator < (const data &a,const data &b) { return a.x>b.x; }};int dis[maxn],vis[maxn],head[maxn],cnt,n,m;priority_queue<data> q;void insert(int u,int v,int w) { e[++cnt].to=v;e[cnt].next=head[u];head[u]=cnt;e[cnt].w=w;}void Dijistra() { data x,y; x.x=0;x.num=1; for (int i=1;i<=n;i++) dis[i]=inf; dis[1]=0; q.push(x); while (q.size()) { x=q.top();q.pop(); if (vis[x.num]) continue; vis[x.num]=1; for (int i=head[x.num];i;i=e[i].next) if (e[i].w+x.x<dis[e[i].to] && !vis[e[i].to]) { y.num=e[i].to; dis[e[i].to]=y.x=e[i].w+x.x; q.push(y); } }}int main() { scanf("%d%d",&n,&m); for (int u,v,w,i=1;i<=m;i++) { scanf("%d%d%d",&u,&v,&w); insert(u,v,w); } Dijistra(); printf("%d",dis[n]); return 0;}
- SPFA(ke,多么优秀的算法,常数爆炸= =):不能处理负环(最短路情况下),正环(最长路情况下)
// poj1201#include<algorithm>#include<iostream>#include<cstdlib>#include<cstring>#include<cstdio>#include<cmath>#include<queue>#define LL long long#define inf 2147483640#define MOD 998244353#define Pi acos(-1.0)#define free(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout);using namespace std;inline LL getint() { int f,x=0;char ch=getchar(); while (ch<='0' || ch>'9') {if (ch=='-') f=-1;else f=1;ch=getchar();} while (ch>='0' && ch<='9') {x=x*10+ch-'0';ch=getchar();} return x*f;}const int maxn=50010;struct edge {int to,w,next;}e[maxn<<2];int vis[maxn],dis[maxn],head[maxn],n,cnt,L,R;void insert(int u,int v,int w) { e[++cnt].to=v;e[cnt].next=head[u];head[u]=cnt;e[cnt].w=w;}int SPFA() { queue<int> q; for (int i=L;i<=R;i++) { vis[i]=1; dis[i]=0; q.push(i); } while (q.size()) { int x=q.front(); q.pop(); vis[x]=0; for (int i=head[x];i;i=e[i].next) if (e[i].w+dis[x]>dis[e[i].to]) { dis[e[i].to]=e[i].w+dis[x]; if (!vis[e[i].to]) {vis[e[i].to]=1;q.push(e[i].to);} } } return dis[R];}int main() { while (scanf("%d",&n)!=EOF) { memset(head,0,sizeof(head)); L=inf,R=0; for (int u,v,w,i=1;i<=n;i++) { scanf("%d%d%d",&u,&v,&w); insert(u-1,v,w); L=min(L,u-1); R=max(R,v); } for (int i=L;i<=R;i++) { insert(i,i+1,0); insert(i+1,i,-1); } printf("%d\n",SPFA()); } return 0;}
差分约束
- >=,求最小值,做最长路;<=,求最大值,做最短路。 还有就是有最短路负环(最长路正环)的话说明无解。答案为inf(-inf)时为任意解。
// poj3159#include<algorithm>#include<iostream>#include<cstdlib>#include<cstring>#include<cstdio>#include<cmath>#include<queue>#define LL long long#define inf 2147483640#define MOD 998244353#define Pi acos(-1.0)#define free(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout);using namespace std;inline LL getint() { int f,x=0;char ch=getchar(); while (ch<='0' || ch>'9') {if (ch=='-') f=-1;else f=1;ch=getchar();} while (ch>='0' && ch<='9') {x=x*10+ch-'0';ch=getchar();} return x*f;}const int maxn=30010,maxm=150010;struct edge {int to,next,w;}e[maxm];struct data { int x,num; friend bool operator < (const data &a,const data &b) { return a.x>b.x; }};int dis[maxn],vis[maxn],head[maxn],cnt,n,m;priority_queue<data> q;void insert(int u,int v,int w) { e[++cnt].to=v;e[cnt].next=head[u];head[u]=cnt;e[cnt].w=w;}void Dijistra() { data x,y; x.x=0;x.num=1; for (int i=1;i<=n;i++) dis[i]=inf; dis[1]=0; q.push(x); while (q.size()) { x=q.top();q.pop(); if (vis[x.num]) continue; vis[x.num]=1; for (int i=head[x.num];i;i=e[i].next) if (e[i].w+x.x<dis[e[i].to] && !vis[e[i].to]) { y.num=e[i].to; dis[e[i].to]=y.x=e[i].w+x.x; q.push(y); } }}int main() { scanf("%d%d",&n,&m); for (int u,v,w,i=1;i<=m;i++) { scanf("%d%d%d",&u,&v,&w); insert(u,v,w); } Dijistra(); printf("%d",dis[n]); return 0;}
Tarjan
- 强连通分量
// poj2186#include<algorithm>#include<iostream>#include<cstring>#include<cstdlib>#include<cstdio>#include<cmath>#include<set>#define MOD 1000000007#define inf 2147483640#define LL long long#define free(a) freopen(a".in","r",stdin);freopen(a".out","w",stdout);using namespace std;inline LL getint() { LL x=0,f=1;char ch=getchar(); while (ch>'9' || ch<'0') {if (ch=='-') f=-1;ch=getchar();} while (ch>='0' && ch<='9') {x=x*10+ch-'0';ch=getchar();} return x*f;}const int maxn=50010;struct edge {int to,next;}e[maxn<<2];int f[maxn],dfn[maxn],low[maxn],head[maxn],s[maxn],pos[maxn],cnts[maxn];int ind,cnt,n,m,top,tot;void insert(int u,int v) { e[++cnt].to=v;e[cnt].next=head[u];head[u]=cnt;}void Tarjan(int u) { dfn[u]=low[u]=++ind; s[++top]=u; f[u]=1; for (int i=head[u];i;i=e[i].next) { if (!dfn[e[i].to]) { Tarjan(e[i].to); low[u]=min(low[u],low[e[i].to]); } else if (f[e[i].to]) low[u]=min(low[u],dfn[e[i].to]); } if (dfn[u]==low[u]) { tot++;int j; do { j=s[top--]; pos[j]=tot; cnts[tot]++; f[j]=0; }while (j!=u); }}int main() { while (scanf("%d%d",&n,&m)!=EOF) { top=0;cnt=0;ind=0;tot=0; for (int i=1;i<=n;i++) dfn[i]=low[i]=head[i]=cnts[i]=pos[i]=0; for (int i=1;i<=m;i++) { int x,y; scanf("%d%d",&x,&y); insert(x,y); } for (int i=1;i<=n;i++) if (!dfn[i]) Tarjan(i); cnt=0;for (int i=1;i<=n;i++) f[i]=0; for (int i=1;i<=n;i++) for (int j=head[i];j;j=e[j].next) if (pos[i]!=pos[e[j].to]) f[pos[i]]++; int ans=0; for (int i=1;i<=tot;i++) if (!f[i]) ans++; if (ans>1) printf("0\n"); else { ans=0; for (int i=1;i<=tot;i++) if (!f[i]) ans+=cnts[i]; printf("%d\n",ans); } } return 0;}
- 割点
// poj1144#include<algorithm>#include<iostream>#include<cstring>#include<cstdlib>#include<cstdio>#include<cmath>#include<set>#define MOD 1000000007#define inf 2147483640#define LL long long#define free(a) freopen(a".in","r",stdin);freopen(a".out","w",stdout);using namespace std;inline LL getint() { LL x=0,f=1;char ch=getchar(); while (ch>'9' || ch<'0') {if (ch=='-') f=-1;ch=getchar();} while (ch>='0' && ch<='9') {x=x*10+ch-'0';ch=getchar();} return x*f;}const int maxn=200;struct edge {int to,next;}e[maxn<<2];int head[maxn],p[maxn],dfn[maxn],low[maxn],f[maxn];int cnt,root,n,ind;void insert(int u,int v) { e[++cnt].to=v;e[cnt].next=head[u];head[u]=cnt; e[++cnt].to=u;e[cnt].next=head[v];head[v]=cnt;}void Tarjan(int u,int fa) { dfn[u]=low[u]=++ind; f[u]=1; for (int i=head[u];i;i=e[i].next) if (e[i].to!=fa) { if (!f[e[i].to]) { Tarjan(e[i].to,u); low[u]=min(low[u],low[e[i].to]); if (low[e[i].to]>=dfn[u] && u!=1) p[u]++; else if (u==1) root++; } else low[u]=min(low[u],dfn[e[i].to]); }}int main() { while (scanf("%d",&n)!=EOF && n) { for (int i=1;i<=n;i++) head[i]=low[i]=dfn[i]=f[i]=p[i]=0; int u,v;cnt=root=ind=0; while (scanf("%d",&u)!=EOF && u) while (getchar()!='\n') { scanf("%d",&v); insert(u,v); } Tarjan(1,0); int ans=0; if (root>1) ans++; for (int i=2;i<=n;i++) if (p[i]) ans++; printf("%d\n",ans); } return 0;}
- 桥
// poj3177#include<algorithm>#include<iostream>#include<cstring>#include<cstdlib>#include<cstdio>#include<cmath>#include<set>#define MOD 1000000007#define inf 2147483640#define LL long long#define free(a) freopen(a".in","r",stdin);freopen(a".out","w",stdout);using namespace std;inline LL getint() { LL x=0,f=1;char ch=getchar(); while (ch>'9' || ch<'0') {if (ch=='-') f=-1;ch=getchar();} while (ch>='0' && ch<='9') {x=x*10+ch-'0';ch=getchar();} return x*f;}const int maxn=10010;struct edge {int to,next;}e[maxn<<2];int f[maxn],dfn[maxn],vis[maxn],low[maxn],head[maxn],bridge[maxn][2],cnts[maxn];int cnt,ind,s,n,m;void insert(int u,int v) { e[++cnt].to=v;e[cnt].next=head[u];head[u]=cnt; e[++cnt].to=u;e[cnt].next=head[v];head[v]=cnt;}int find(int x) { return x==f[x] ? x : f[x]=find(f[x]);}void Tarjan(int u,int fa) { dfn[u]=low[u]=++ind; vis[u]=1; for (int i=head[u];i;i=e[i].next) if (e[i].to!=fa) { if (!vis[e[i].to]) { Tarjan(e[i].to,u); low[u]=min(low[u],low[e[i].to]); if (dfn[u]<low[e[i].to]) { bridge[++s][0]=u; bridge[s][1]=e[i].to; } else { int r1=find(u),r2=find(e[i].to); f[r1]=r2; } } else low[u]=min(low[u],dfn[e[i].to]); }} int main() { while (scanf("%d%d",&n,&m)!=EOF) { cnt=ind=s=0; for (int i=1;i<=n;i++) head[i]=dfn[i]=low[i]=vis[i]=cnts[i]=0; for (int i=1;i<=m;i++) { int x,y; scanf("%d%d",&x,&y); insert(x,y); } for (int i=1;i<=n;i++) f[i]=i; Tarjan(1,-1); for (int i=1;i<=s;i++) { cnts[find(bridge[i][0])]++; cnts[find(bridge[i][1])]++; } int ans=0; for (int i=1;i<=n;i++) if (cnts[i]==1) ans++; printf("%d\n",(ans+1)/2); } return 0;}
- 双连通分量
- 缩点
拓扑排序
1 0
- NOIP提高组知识要点(搭建中)
- NOIP做题记录(提高组)
- NOIP 2006(提高组T1)
- NOIP提高组 单峰
- NOIP提高组 积木
- NOIP提高组 看电影
- NOIP提高组 鼎纹
- NOIP提高组 千帆渡
- NOIP提高组 Brothers
- NOIP提高组 Crisis
- NOIP提高组 Word
- NOIP提高组 闭门造车
- NOIP提高组 爬山
- 【NOIP提高组】爬山
- 【NOIP提高组】Map
- 【NOIP提高组】矩阵
- 【NOIP提高组】整除
- 【NOIP提高组】神炎皇
- Kinect学习笔记二DepthFrame
- Android Studio安装导致Myeclipse 2014Android SDK无法使用
- 随机过程及应用(一) - 特征函数
- C语言_密码不回显+"*"函数
- 腾讯笔试编程题--小Q上厕所
- NOIP提高组知识要点(搭建中)
- 最经典的java 23种设计模式及具体例子
- 百度云管家登录时提示密码错误
- 配置eclipse使用gradle本地包
- java单链表实现
- iOS开发之protocol和delegate
- 关于NFS服务的mount: RPC: Timed out问题
- hadoop 与 ssh 免密码设置
- Kinect学习笔记三BodyIndex