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
原创粉丝点击