zoukankan      html  css  js  c++  java
  • 图论总结(一)

    这几天做了一些图论的题目,现总结一下。

    代码:

    //uva11374
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<iostream>
    using namespace std;
    
    const int N=1100,M=50010;
    int n,m,len,num,sl,cnt,bl;
    int first[N],bf[N],dfn[N],low[N],sccno[N],size[N],s[N],d[N];
    struct node{
        int x,y,next;
    }a[M],b[M];
    
    int minn(int x,int y){return x<y ? x:y;}
    int maxx(int x,int y){return x>y ? x:y;}
    
    void ins(int x,int y,bool bk)
    {
        if(!bk)
        {
            len++;
            a[len].x=x;a[len].y=y;
            a[len].next=first[x];first[x]=len;    
        }
        else{
            bl++;
            b[bl].x=x;b[bl].y=y;
            b[bl].next=bf[x];bf[x]=bl;
        }
    }
    
    void tarjan(int x,int fa)
    {
        dfn[x]=low[x]=++num;
        s[++sl]=x;
        for(int i=first[x];i;i=a[i].next)
        {
            int y=a[i].y;
            if(!dfn[y]) {
                tarjan(y,x);
                low[x]=minn(low[x],low[y]);
            }
            else if(!sccno[y]) low[x]=minn(low[x],dfn[y]);
        }
        if(dfn[x]==low[x])
        {
            cnt++;
            int z=0;
            while(z!=x)
            {
                z=s[sl];
                sccno[z]=cnt;
                size[cnt]++;
                sl--;
            }
        }
    }
    
    int dp(int x)
    {
        if(d[x]) return d[x];
        d[x]=size[x];
        for(int i=bf[x];i;i=b[i].next)
        {
            int y=b[i].y;
            d[x]=maxx(d[x],dp(y)+size[x]);
        }
        return d[x];
    }
    
    int main()
    {
        freopen("a.in","r",stdin);
        freopen("a.out","w",stdout);
        int T;
        scanf("%d",&T);
        while(T--)
        {
            scanf("%d%d",&n,&m);
            len=0;num=0;sl=0;cnt=0;bl=0;
            memset(bf,0,sizeof(bf));
            memset(first,0,sizeof(first));
            memset(dfn,0,sizeof(dfn));
            memset(sccno,0,sizeof(sccno));
            memset(size,0,sizeof(size));
            memset(d,0,sizeof(d));
            for(int i=1;i<=m;i++)
            {
                int x,y;
                scanf("%d%d",&x,&y);
                ins(x,y,0);
            }
            for(int i=1;i<=n;i++)
                if(!dfn[i]) tarjan(i,0);
            for(int i=1;i<=len;i++)
            {
                int x=a[i].x;
                int y=a[i].y;
                if(sccno[x]!=sccno[y]) ins(sccno[x],sccno[y],1);
            }
            int ans=0;
            for(int i=1;i<=cnt;i++) ans=maxx(ans,dp(i));
            printf("%d
    ",ans);
        }
        return 0;
    }
    uva11374
    //uva10917
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<iostream>
    #include<queue>
    using namespace std;
    
    const int N=1100,M=N*N;
    int n,m,len;
    int first[N],dis[N],f[N];
    bool vis[N];
    struct node{
        int x,y,d,next;
    }a[M];
    queue<int> q;
    
    void ins(int x,int y,int d)
    {
        len++;
        a[len].x=x;a[len].y=y;a[len].d=d;
        a[len].next=first[x];first[x]=len;
    }
    
    void spfa(int s)
    {
        memset(dis,63,sizeof(dis));
        memset(vis,0,sizeof(vis));
        while(!q.empty()) q.pop();
        q.push(s);vis[s]=1;dis[s]=0;
        while(!q.empty())
        {
            int x=q.front();q.pop();
            vis[x]=0;
            for(int i=first[x];i;i=a[i].next)
            {
                int y=a[i].y;
                if(dis[y] > dis[x]+a[i].d)
                {
                    dis[y]=dis[x]+a[i].d;
                    if(!vis[y]) vis[y]=1,q.push(y);
                }
            }
        }
    }
    
    int dp(int x)
    {
        if(vis[x]) return f[x];
        vis[x]=1;
        for(int i=first[x];i;i=a[i].next) 
            if(dis[a[i].y]<dis[x]) f[x]+=dp(a[i].y);
        return f[x];
    }
    
    int main()
    {
        freopen("a.in","r",stdin);
        freopen("a.out","w",stdout);
        while(1)
        {
            scanf("%d",&n);
            if(!n) return 0;
            scanf("%d",&m);
            len=0;
            memset(first,0,sizeof(first));
            for(int i=1;i<=m;i++)
            {
                int x,y,d;
                scanf("%d%d%d",&x,&y,&d);
                ins(x,y,d),ins(y,x,d);
            }
            spfa(2);
            memset(f,0,sizeof(f));
            memset(vis,0,sizeof(vis));
            f[2]=1;vis[2]=1;
            printf("%d
    ",dp(1));
        }
        return 0;
    }
    uva10917
    //LA4080/uva1416
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<iostream>
    #include<queue>
    using namespace std;
    
    typedef long long LL;
    const int N=110,M=1100,INF=(int)1e9;
    int n,m,l,len;
    int first[N],dis[N],p[N];
    LL ans0,ans[2*M];
    bool vis[N];
    struct node{
        int x,y,d,next;
        bool bk,t;
    }a[2*M];
    queue<int> q;
    
    LL maxx(LL x,LL y){return x>y ? x:y;}
    
    void ins(int x,int y,int d)
    {
        len++;
        a[len].bk=1;a[len].t=0;
        a[len].x=x;a[len].y=y;a[len].d=d;
        a[len].next=first[x];first[x]=len;
    }
    
    void spfa(int s,bool tmp)
    {
        while(!q.empty()) q.pop();
        memset(vis,0,sizeof(vis));
        memset(dis,63,sizeof(dis));
        q.push(s);vis[s]=1;dis[s]=0;
        while(!q.empty())
        {
            int x=q.front();vis[x]=0;q.pop();
            for(int i=first[x];i!=-1;i=a[i].next)
            {
                if(!a[i].bk) continue;
                int y=a[i].y;
                if(dis[y]>dis[x]+a[i].d)
                {
                    dis[y]=dis[x]+a[i].d;
                    if(!vis[y]) vis[y]=1,q.push(y);
                }
            }
        }
        if(tmp)
        {
            for(int i=0;i<len;i++)
            {
                a[i].t=0;
                int x=a[i].x,y=a[i].y;
                if(dis[x]==dis[y]+a[i].d) a[i].t=a[i^1].t=1;
            }    
        }
    }
    
    int get(int x)
    {
        int sum=0;
        for(int i=1;i<=n;i++)
            if(dis[i]<INF) sum+=dis[i];
            else sum+=l;
        return sum;
    }
    
    void find()
    {
        for(int i=1;i<=n;i++)
        {
            spfa(i,1);
            int now=get(i);
            ans0+=now;
            for(int k=0;k<len;k++)
            {
                int x=a[k].x,y=a[k].y;
                if(a[k].t) 
                {
                    a[k].bk=0;a[k^1].bk=0;
                    spfa(i,0);
                    a[k].bk=1;a[k^1].bk=1;
                    ans[k]+=get(i);
                }
                else ans[k]+=now;
            }
        }
    }
    
    int main()
    {
        freopen("a.in","r",stdin);
        freopen("a.out","w",stdout);
        while(scanf("%d%d%d",&n,&m,&l)!=EOF)
        {
            len=-1;ans0=0;
            memset(first,-1,sizeof(first));
            memset(ans,0,sizeof(ans));
            for(int i=1;i<=m;i++)
            {
                int x,y,d;
                scanf("%d%d%d",&x,&y,&d);
                ins(x,y,d),ins(y,x,d);
            }
            find();
            LL mx=ans0;
            for(int i=0;i<len;i++)
                mx=maxx(mx,ans[i]);
            printf("%lld %lld
    ",ans0,mx);
        }
        return 0;
    }
    LA1416 uva4080
    //uva10537
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<iostream>
    #include<queue>
    #include<cmath>
    using namespace std;
    
    typedef long long LL;
    const int N=1010,M=200010;
    int n,m,len,st,ed,al;
    int first[N],p[N],ans[N];
    LL d[N];
    bool vis[N];
    struct node{
        int x,y,next;
    }a[M];
    queue<int> q;
    
    void ins(int x,int y)
    {
        len++;
        a[len].x=x;a[len].y=y;
        a[len].next=first[x];first[x]=len;
    }
    
    void spfa(int s)
    {
        while(!q.empty()) q.pop();
        memset(vis,0,sizeof(vis));
        memset(d,127,sizeof(d));
        memset(p,-1,sizeof(p));
        q.push(s);vis[s]=1;d[s]=n;
        while(!q.empty())
        {
            int x=q.front();vis[x]=0;q.pop();
            LL now=d[x];
            if(x>=32) now=d[x]+1;//a~z
            else
            {
                now=(LL)d[x]*20/19;
                while(now-(LL)ceil(now/20.0)<d[x]) now++;
            }
            for(int i=first[x];i;i=a[i].next)
            {
                int y=a[i].y;
                if(d[y]>now)
                {
                    d[y]=now;
                    p[y]=x;
                    if(!vis[y]) vis[y]=1,q.push(y);
                }
                if(d[y]==now && x<p[y]) p[y]=x;
            }
        }
    }
    
    int main()
    {
        freopen("a.in","r",stdin);
        freopen("a.out","w",stdout);
        int T=0;
        while(1)
        {
            scanf("%d",&m);getchar();
            if(m==-1) return 0;
            printf("Case %d:
    ",++T);
            len=0;
            memset(first,0,sizeof(first));
            char x,y,c;
            for(int i=1;i<=m;i++)
            {
                scanf("%c%c%c",&x,&c,&y);getchar();
                ins(x-'A',y-'A');
                ins(y-'A',x-'A');
            }
            scanf("%d",&n);getchar();
            scanf("%c%c%c",&x,&c,&y);
            st=x-'A',ed=y-'A';
            spfa(ed);
            int now=st;al=1;ans[1]=st;
            while(p[now]!=-1) ans[++al]=p[now],now=p[now];
            printf("%lld
    ",d[st]);
            for(int i=1;i<al;i++)
                printf("%c-",ans[i]+'A');
            printf("%c
    ",ed+'A');
        }
        return 0;
    }
    uva10537
    /*
    uva11090
    该程序没有AC,对拍发现有些数据和答案差了0.01,
    估计是精度问题(这个程序确定的范围更小,我觉得是对的)
    */
    
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<iostream>
    #include<queue>
    #include<cmath>
    using namespace std;
    
    const int N=60,M=60*60*2;
    double INF=(double)1e9;
    int n,m,len;
    int first[N],p[N];
    double dis[N];
    bool vis[N];
    struct node{
        int x,y,next;
        double d;
    }a[M];
    queue<int> q;
    
    double maxx(double x,double y){return x>y ? x:y;}
    double minn(double x,double y){return x<y ? x:y;}
    
    void ins(int x,int y,double d)
    {
        len++;
        a[len].x=x;a[len].y=y;a[len].d=d;
        a[len].next=first[x];first[x]=len;
    }
    
    bool spfa(int s)
    {
        while(!q.empty()) q.pop();
        memset(vis,0,sizeof(vis));
        memset(p,0,sizeof(p));
        for(int i=1;i<=n;i++) dis[i]=INF;
        q.push(s);vis[s]=1;dis[s]=0;
        while(!q.empty())
        {
            int x=q.front();p[x]++;vis[x]=0;q.pop();
            if(p[x]>=n) return 1;
            for(int i=first[x];i;i=a[i].next)
            {
                int y=a[i].y;
                if(dis[y]>(dis[x]+a[i].d))
                {
                    dis[y]=dis[x]+a[i].d;
                    if(!vis[y]) vis[y]=1,q.push(y);
                }
            }
        }
        return 0;
    }
    
    bool check(double c)
    {
        for(int i=1;i<=len;i++) a[i].d-=c;
        bool bk=0;
        for(int i=1;i<=n;i++)
        {
            bk=spfa(i);
            if(bk==1) break;
        }
        for(int i=1;i<=len;i++) a[i].d+=c;
        return bk;
    }
    
    int main()
    {
        freopen("a.in","r",stdin);
        freopen("a.out","w",stdout);
        int T;
        scanf("%d",&T);
        for(int TT=1;TT<=T;TT++)
        {
            printf("Case #%d: ",TT);
            scanf("%d%d",&n,&m);
            len=0;
            memset(first,0,sizeof(first));
            double mx=0,mn=INF;
            for(int i=1;i<=m;i++)
            {
                int x,y;
                double d;
                scanf("%d%d%lf",&x,&y,&d);
                mx=maxx(mx,d);
                mn=minn(mn,d);
                ins(x,y,d);
            }
            double l=mn,r=mx,mid;
            double ans=-1;
            // printf("r = %lf  mx = %lf
    ",r,mx);
            if(!check(mx+1)) printf("No cycle found.
    ");
            else{
                while(l<r && (r-l)>(1e-3))
                {
                    mid=(l+r)/2;//l+(r-l)/2;
                    if(check(mid)) r=mid;
                    else l=mid;
                }
                printf("%.2lf
    ",l);
            }        
        }
        return 0;
    }
    uva11090
    //uva11478
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<iostream>
    #include<queue>
    #include<cmath>
    using namespace std;
    
    const int N=550,M=4000;
    int n,m,len,ql;
    int first[N],dis[N],cnt[N],sum[N],q[N];
    bool vis[N];
    struct node{
        int x,y,d,next;
    }a[M];
    
    void ins(int x,int y,int d)
    {
        len++;
        a[len].x;a[len].y=y;a[len].d=d;
        a[len].next=first[x];first[x]=len;
    }
    
    bool spfa(int s)
    {
        ql=0;
        memset(dis,63,sizeof(dis));
        memset(vis,0,sizeof(vis));
        memset(cnt,0,sizeof(cnt));
        q[++ql]=s;vis[s]=1;dis[s]=0;
        while(ql)
        {
            int x=q[ql];ql--;vis[x]=0;cnt[x]++;
            if(cnt[x]==n+1) return 0;
            for(int i=first[x];i;i=a[i].next)
            {
                int y=a[i].y;
                if(dis[y]>dis[x]+a[i].d)
                {
                    dis[y]=dis[x]+a[i].d;
                    if(!vis[y]) vis[y]=1,q[++ql]=y;
                }
            }
        }
        return 1;
    }
    
    bool check(int c)
    {
        for(int i=1;i<=len;i++) a[i].d-=c;
        bool bk=spfa(0);
        for(int i=1;i<=len;i++) a[i].d+=c;
        return bk;
    }
    
    int main()
    {
        freopen("a.in","r",stdin);
        freopen("a.out","w",stdout);
        while(scanf("%d%d",&n,&m)!=EOF)
        {
            len=0;
            memset(first,0,sizeof(first));
            memset(sum,0,sizeof(sum));
            for(int i=1;i<=n;i++) ins(0,i,0);
            for(int i=1;i<=m;i++)
            {
                int x,y,d;
                scanf("%d%d%d",&x,&y,&d);
                ins(x,y,d);
            }
            if(check(10010)) printf("Infinite
    ");
            else
            {
                if(!check(1)) printf("No Solution
    ");
                else
                {
                    int l=1,r=10000;
                    while(l<r)
                    {
                        int mid=(l+r+1)/2;
                        if(check(mid)) l=mid;
                        else r=mid-1;
                        if(l==r) break;
                    }
                    printf("%d
    ",l);
                }
            }
        }
        return 0;
    }
    uva11478
    //poj1201
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<iostream>
    #include<queue>
    #include<cmath>
    using namespace std;
    
    const int N=50100,M=4*50100;
    int m,len,ql,mx;
    int first[N],dis[N],q[N];
    bool vis[N];
    struct node{
        int x,y,d,next;
    }a[M];
    
    int maxx(int x,int y){return x>y ? x:y;}
    
    void ins(int x,int y,int d)
    {
        len++;
        a[len].x=x;a[len].y=y;a[len].d=d;
        a[len].next=first[x];first[x]=len;
    }
    
    int spfa(int s)
    {
        ql=0;
        memset(dis,-1,sizeof(dis));
        memset(vis,0,sizeof(vis));
        q[++ql]=s;vis[s]=1;dis[s]=0;
        while(ql)
        {
            int x=q[ql];ql--;vis[x]=0;
            for(int i=first[x];i;i=a[i].next)
            {
                int y=a[i].y;
                if(dis[y]<dis[x]+a[i].d)
                {
                    dis[y]=dis[x]+a[i].d;
                    if(!vis[y]) vis[y]=1,q[++ql]=y;
                }
            }
        }
        return dis[mx];
    }
    
    int main()
    {
        freopen("a.in","r",stdin);
        freopen("a.out","w",stdout);
        len=0;
        memset(first,0,sizeof(first));
        scanf("%d",&m);
        mx=-1;
        for(int i=1;i<=m;i++)
        {
            int x,y,d;
            scanf("%d%d%d",&x,&y,&d);
            x++;y++;
            ins(x-1,y,d);
            mx=maxx(mx,y);
        }
        for(int i=0;i<=mx;i++) ins(i,i+1,0);
        for(int i=1;i<=mx;i++) ins(i,i-1,-1);
        /*
        0<=dis[i]-dis[i-1]<=1
        注意要建 i-->i+1 和 i-->i-1 两种辅助边
        如果不建dis[i]-dis[i-1]<=1这条边就会出现一个数选了多遍的情况
        */
        printf("%d
    ",spfa(0));
        return 0;
    }
    poj1201
    //poj1275
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<iostream>
    #include<queue>
    #include<cmath>
    using namespace std;
    
    const int N=30,M=1100;
    int n,len;
    int num[N],lim[N],cnt[N],dis[N],first[N];
    bool vis[N];
    struct node{
        int x,y,d,next;
    }a[M];
    queue<int> q;
    
    void ins(int x,int y,int d)
    {
        len++;
        a[len].x=x;a[len].y=y;a[len].d=d;
        a[len].next=first[x];first[x]=len;
    }
    
    bool spfa(int s,int now)
    {
        for(int i=len;i>=len-6;i--) a[i].d-=now;
        a[1].d+=now;
        bool bk=1;
        while(!q.empty()) q.pop();
        memset(vis,0,sizeof(vis));
        memset(dis,-63,sizeof(dis));
        memset(cnt,0,sizeof(cnt));
        q.push(s);vis[s]=1;dis[s]=0;
        while(!q.empty())
        {
            int x=q.front();q.pop();vis[x]=0;cnt[x]++;
            if(cnt[x]>=25) {bk=0;break;}
            for(int i=first[x];i;i=a[i].next)
            {
                int y=a[i].y;
                if(dis[y]<dis[x]+a[i].d)
                {
                    dis[y]=dis[x]+a[i].d;
                    if(!vis[y]) vis[y]=1,q.push(y);
                }
            }
        }
        a[1].d-=now;
        for(int i=len;i>=len-6;i--) a[i].d+=now;
        return bk;
    }
    
    int main()
    {
        freopen("a.in","r",stdin);
        freopen("a.out","w",stdout);
        int T;
        scanf("%d",&T);
        while(T--)
        {
            len=0;
            memset(first,0,sizeof(first));
            memset(num,0,sizeof(num));
            for(int i=1;i<=24;i++) scanf("%d",&lim[i]);
            scanf("%d",&n);
            for(int i=1;i<=n;i++)
            {
                int x;
                scanf("%d",&x);x++;
                num[x]++;
            }
            ins(0,24,0);
            for(int i=1;i<=24;i++) ins(i-1,i,0);
            for(int i=1;i<=24;i++) ins(i,i-1,-num[i]);
            for(int i=8;i<=24;i++) ins(i-8,i,lim[i]);
            for(int i=1;i<=7;i++) ins(i+16,i,lim[i]);
            if(!spfa(0,n)) printf("No Solution
    ");
            else 
            {
                int l=0,r=n;
                while(l<r)
                {
                    int mid=(l+r)>>1;
                    if(spfa(0,mid)) r=mid;
                    else l=mid+1;
                }
                printf("%d
    ",l);            
            }    
        }
        return 0;
    }
    poj1275
  • 相关阅读:
    IP和MAC
    ASCII,Unicode 和 UTF-8
    php(PHP Hypertext Preprocessor)随笔1
    css层叠样式表 (Cascading Style Sheets)初识
    ansible部署
    mysql三种备份方式
    nginx反向代理,负载均衡,动静分离,rewrite地址重写介绍
    Maven安装和配置
    jenkins之Tomcat7+jdk1.7+jenkins
    CentOS 7.0如何安装配置iptables和seLinux以及firewalld
  • 原文地址:https://www.cnblogs.com/KonjakJuruo/p/5401030.html
Copyright © 2011-2022 走看看