图论总结(一)

图论总结(一)

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

 

代码:

//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 拦路雨偏似雪花 阅读( ...) 评论( ...) 编辑 收藏
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
amber大牛的图论总结 1. 图论 Graph Theory 1.1. 定义与术语 Definition and Glossary 1.1.1. 图与网络 Graph and Network 1.1.2. 图的术语 Glossary of Graph 1.1.3. 路径与回路 Path and Cycle 1.1.4. 连通性 Connectivity 1.1.5. 图论中特殊的集合 Sets in graph 1.1.6. 匹配 Matching 1.1.7. 树 Tree 1.1.8. 组合优化 Combinatorial optimization 1.2. 图的表示 Expressions of graph 1.2.1. 邻接矩阵 Adjacency matrix 1.2.2. 关联矩阵 Incidence matrix 1.2.3. 邻接表 Adjacency list 1.2.4. 弧表 Arc list 1.2.5. 星形表示 Star 1.3. 图的遍历 Traveling in graph 1.3.1. 深度优先搜索 Depth first search (DFS) 1.3.1.1. 概念 1.3.1.2. 求无向连通图中的桥 Finding bridges in undirected graph 1.3.2. 广度优先搜索 Breadth first search (BFS) 1.4. 拓扑排序 Topological sort 1.5. 路径与回路 Paths and circuits 1.5.1. 欧拉路径或回路 Eulerian path 1.5.1.1. 无向图 1.5.1.2. 有向图 1.5.1.3. 混合图 1.5.1.4. 无权图 Unweighted 1.5.1.5. 有权图 Weighed — 中国邮路问题The Chinese post problem 1.5.2. Hamiltonian Cycle 哈氏路径与回路 1.5.2.1. 无权图 Unweighted 1.5.2.2. 有权图 Weighed — 旅行商问题The travelling salesman problem 1.6. 网络优化 Network optimization 1.6.1. 最小生成树 Minimum spanning trees 1.6.1.1. 基本算法 Basic algorithms 1.6.1.1.1. Prim 1.6.1.1.2. Kruskal 1.6.1.1.3. Sollin(Boruvka) 1.6.1.2. 扩展模型 Extended models 1.6.1.2.1. 度限制生成树 Minimum degree-bounded spanning trees 1.6.1.2.2. k小生成树 The k minimum spanning tree problem(k-MST) 1.6.2. 最短路Shortest paths 1.6.2.1. 单源最短路 Single-source shortest paths 1.6.2.1.1. 基本算法 Basic algorithms 1.6.2.1.1.1. Dijkstra 1.6.2.1.1.2. Bellman-Ford 1.6.2.1.1.2.1. Shortest path faster algorithm(SPFA) 1.6.2.1.2. 应用Applications 1.6.2.1.2.1. 差分约束系统 System of difference constraints 1.6.2.1.2.2. 有向无环图上的最短路 Shortest paths in DAG 1.6.2.2. 所有顶点对间最短路 All-pairs shortest paths 1.6.2.2.1. 基本算法 Basic algorithms 1.6.2.2.1.1. Floyd-Warshall 1.6.2.2.1.2. Johnson 1.6.3. 网络流 Flow network 1.6.3.1. 最大流 Maximum flow 1.6.3.1.1. 基本算法 Basic algorithms 1.6.3.1.1.1. Ford-Fulkerson method 1.6.3.1.1.1.1. Edmonds-Karp algorithm 1.6.3.1.1.1.1.1. Minimum length path 1.6.3.1.1.1.1.2. Maximum capability path 1.6.3.1.1.2. 预流推进算法 Preflow push method 1.6.3.1.1.2.1. Push-relabel 1.6.3.1.1

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值