图论总结(一)

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

 

代码:

//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\n",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\n",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\n",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:\n",++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\n",d[st]);
        for(int i=1;i<al;i++)
            printf("%c-",ans[i]+'A');
        printf("%c\n",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\n",r,mx);
        if(!check(mx+1)) printf("No cycle found.\n");
        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\n",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\n");
        else
        {
            if(!check(1)) printf("No Solution\n");
            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\n",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\n",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\n");
        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\n",l);            
        }    
    }
    return 0;
}
poj1275

 

posted @ 2016-04-17 14:39  拦路雨偏似雪花  阅读(297)  评论(0编辑  收藏  举报