zoukankan      html  css  js  c++  java
  • 暑假图论练习

    1.Aizu - 0189比较水的题把

    #include<iostream>
    #include<string.h>
    #include<algorithm>
    #define inf 0x3f3f3f
    using namespace std;
    int map[100][100];
    int dis[100];
    int vis[100];
    void djst(int s)
    {
        memset(vis,0,sizeof(vis));
        memset(dis,inf,sizeof(dis));
        dis[s]=0;
        while(1)
        {
            int k=-1,minn=inf+1;
            for(int i=0;i<10;i++)
            {
                if(!vis[i]&&dis[i]<minn)
                k=i,minn=dis[i];
            }
            if(k==-1) break;
            vis[k]=1;
            for(int i=0;i<10;i++)
            dis[i]=min(dis[i],dis[k]+map[k][i]);
        }
        
    }
    int main()
    {
        int n;
        while(cin>>n)
        {
            memset(map,inf,sizeof(map));
            if(n==0) break;
            int nn=0;
            for(int i=0;i<n;i++)
            {
                int a,b,c;
                cin>>a>>b>>c;
                nn=max(nn,max(a,b));
                if(map[a][b]>c)
                map[a][b]=map[b][a]=c;
            }
            int minn=inf,tt;
            for(int i=0;i<=nn;i++)
            {
                djst(i);
                int sum=0;
                for(int i=0;i<=nn;i++)
                {
                    if(dis[i]!=inf)
                    sum+=dis[i];
                }
                if(minn>sum)
                {
                    minn=sum;
                    tt=i;
                }
            }
            cout<<tt<<" "<<minn<<endl;
        }
        
    }
    View Code

    2.POJ - 2139 简单对数据处理一下,变成图就行  最后注意double

    #include<iostream>
    #include<string.h>
    #include<algorithm>
    #include<math.h>
    #include<stdio.h>
    #define inf 0x3f3f3f
    using namespace std;
    int map[305][305];
    int vis[305];
    int dis[305];
    int n,m;
    
    void prim(int s)
    {
        int minn,k=0;
        memset(vis,0,sizeof(vis));
        for(int i=1;i<=n;++i)
        {
            dis[i]=map[s][i];
        }
        vis[s]=1;
        for(int i=2;i<=n;++i)
        {
            minn=inf;
            for(int j=1;j<=n;++j)
            {
                if(!vis[j]&&minn>dis[j])
                {
                    k=j;
                    minn=dis[j];
                }
            }
            vis[k]=1;
            for(int j=1;j<=n;++j)
            {
                if(!vis[j]&&dis[j]>dis[k]+map[k][j])
                    dis[j]=dis[k]+map[k][j];
            }
        }
    }
    
    int main()
    {
        while(scanf("%d %d",&n,&m)!=EOF)
        {
                for(int i=1;i<=n;++i){
                    for(int j=1;j<=n;++j){
                    if(i==j) map[i][j]=0;
                    else map[i][j]=map[j][i]=inf; 
                    }
                }
            
            while(m--)
            {
                int a,b,c;
                int t[10002];
                cin>>a;
                for(int i=0;i<a;i++)
                {
                    cin>>t[i];
                }
                for(int i=0;i<a-1;i++)
                {
                    for(int j=i+1;j<a;j++)
                    {
                        if(t[i]!=t[j])
                         map[t[i]][t[j]]=map[t[j]][t[i]]=1;
                    }
                }
                /*
                for(int i=1;i<=n;i++)
                {
                    for(int j=1;j<=n;j++)
                    cout<<map[i][j]<<" ";
                    cout<<endl;
                }*/
            }
            double minn=inf;
            for(int i=1;i<=n;i++)
            {
                double sum=0;
                prim(i);
                for(int j=1;j<=n;j++)
                {
                    if(i!=j)
                    sum+=dis[j];
                }
    
                minn=minn>sum*1.0/(n-1)?sum*1.0/(n-1):minn;
            }
            printf("%d
    ",(int)(minn*100));
        }
    }
    View Code

    3.POJ - 3268 

    这个有个小技巧  ,按照一般写会超时  各个点到一个点x的最短距离  可以换成x到各个点的,只需把矩阵反转一下再跑一遍图论算法就可以了

    #include<iostream>
    #include<string.h>
    #include<algorithm>
    #include<stdio.h>
    #define inf 0x3f3f3f
    using namespace std;
    int map[1010][1010];
    int dis[1010];
    int dis1[1010];
    int vis[1010];
    int n,m,x;
    void djst(int s)
    {
        memset(vis,0,sizeof(vis));
        memset(dis,inf,sizeof(dis));
        
        dis[s]=0;
        while(1)
        {
            int k=-1,minn=inf;
            for(int i=1;i<=n;i++)
            {
                if(!vis[i]&&dis[i]<minn)
                k=i,minn=dis[i];
            }
            if(k==-1) break;
            vis[k]=1;
            for(int i=1;i<=n;i++)
            dis[i]=min(dis[i],dis[k]+map[k][i]);
        }
    
    }
    int main()
    {
         while(scanf("%d %d %d",&n,&m,&x)!=EOF)
        {
            memset(map,inf,sizeof(map));
            memset(vis,0,sizeof(vis));
            for(int i=1;i<=n;i++)
            {
                for(int j=1;j<=n;j++)
                {
                    if(i==j) map[i][j]=0;
                    else map[i][j]=inf;
                }
            }
            for(int i=0;i<m;i++)
            {
                int a,b,c;
                cin>>a>>b>>c;
                if(map[a][b]>c)
                map[a][b]=c;
            }
            djst(x);
            for(int i=1;i<=n;i++) dis1[i]=dis[i];
        
        /*    for(int i=1;i<=n;i++)
            {
                for(int j=1;j<=n;j++)
                {
                    cout<<map[i][j]<<"    ";
                }
                cout<<endl;
            }
            cout<<endl;
                for(int i=1;i<=n;i++)
            {
                for(int j=1;j<=n;j++)
                {
                    cout<<map[i][j]<<"    ";
                }
                cout<<endl;
            }
            */
            for(int i=1;i<=n;i++)
            {
                for(int j=1;j<=i;j++)
                {
                swap(map[i][j],map[j][i]);
                }
            }
            int ans=0;
            djst(x);
            for(int i=1;i<=n;i++)
            {
            //    cout<<dis[i]<<" "<<dis1[i]<<endl;
                ans=max(ans,dis[i]+dis1[i]);
            }
            cout<<ans<<endl;
        }
    
        return 0;
     } 
    View Code

    4.Aizu - 2249

    这个有点难度把,注意先保证距离最短,再来判断价格

    邻接矩阵回朝内存  ,要用邻接表的

    #include<bits/stdc++.h>
    using namespace std;
    #define inf 0x3f3f3f
    struct ac{
        int v,dis,cost;
    };
    int n,m;
    int dis[10002];
    int cost[10002];
    int vis[10002];
    vector<ac>rode[10002];
    void djst()
    {
        memset(dis,inf,sizeof(dis));
        memset(cost,inf,sizeof(cost));
        memset(vis,0,sizeof(vis));
        dis[1]=0;
        cost[1]=0;
        while(1) 
        {
            int k=-1,dmin=inf,cmin=inf;
            for(int j=1;j<=n;j++)
            {
                if(!vis[j])
                {
                    if(dis[j]<dmin)
                    k=j,dmin=dis[j],cmin=cost[j];
                    else if(dis[j]==dmin)
                    {
                        if(cost[j]<cmin)
                        k=j,dmin=dis[j],cmin=cost[j];
                    }
                }    
            }
            if(k==-1) return ;
            vis[k]=1;
            
            for(int i=0;i<rode[k].size();i++)
            {
                int j=rode[k][i].v;
                if(!vis[j])
                {
                    if(dis[k]+rode[k][i].dis<dis[j])
                    {
                        dis[j]=dis[k]+rode[k][i].dis;
                        cost[j]=rode[k][i].cost;
                    }
                    else if(dis[k]+rode[k][i].dis==dis[j]&&cost[j]>rode[k][i].cost)
                    {
                        cost[j]=rode[k][i].cost;
                    }
                }
            }
        }
    }
    int main()
    {
        while(cin>>n>>m)
        {
            if(n+m==0) break;
            for(int i=1;i<=m;i++)
            {
                int a,c,b,d;
                cin>>a>>b>>c>>d;
                ac tt;
                tt.v=b,tt.dis=c,tt.cost=d;
                rode[a].push_back(tt);
                tt.v=a;
                rode[b].push_back(tt);
            }
            djst();
            int ans=0;
        //    for(int i=1;i<=n;i++)
        //    cout<<cost[i]<<"   ";
        //    cout<<endl;
            for(int i=1;i<=n;i++){
                rode[i].clear();
                ans+=cost[i];
            }
            cout<<ans<<endl;
        }
        return 0;
    }
    View Code

    这个是超出内存的

    #include<iostream>
    #include<string.h>
    #include<algorithm>
    #include<stdio.h>
    #define inf 0x3f3f3f
    using namespace std;
    int n,m;
    int vis[10001];
    int dis[10001];
    int pre[10001];
    int len[10001][10001];
    int cost[10001][10001];
    void prim()
    {
        memset(dis,inf,sizeof(dis));
        memset(pre,inf,sizeof(pre));
        memset(vis,0,sizeof(vis));
        dis[1]=0;
        pre[1]=0;
        int sum=0;
        while(1)
        {
            
            int k=-1,dmin=inf,cmin;
            for(int i=1;i<=n;i++)
            {
                if(!vis[i])
                {
                    if(dis[i]<dmin)
                    {
                        k=i;
                        dmin=dis[i];
                        cmin=pre[i];
                    }
                    else if(dis[i]==dmin){
                        if(pre[i]<cmin)
                        {
                            k=i;
                            dmin=dis[i];
                            cmin=pre[i];
                        }
                    }
                }
            }
            if(k==-1) return;
            vis[k]=1;
            for(int i=1;i<=n;i++)
            {
                if(!vis[i])
                {
                        if(dis[i]>dis[k]+len[k][i])
                    {
                        dis[i]=dis[k]+len[k][i];
                        pre[i]=cost[k][i];
                    }
                    else if(dis[i]==dis[k]+len[k][i]&&pre[i]>cost[k][i])
                    {
                        pre[i]=cost[k][i];
                    }
                }
            }
        }
    }
    int main()
    {
        while(scanf("%d%d",&n,&m),n+m){
            for(int i=1;i<=n;i++)
            {
                for(int j=1;j<=n;j++)
                {
                    if(i==j) len[i][j]=len[j][i]=0,cost[i][j]=cost[j][i]=0;
                    else len[i][j]=len[j][i]=inf,cost[i][j]=cost[j][i]=inf;
                }
            }
            while(m--){
                int a,b,c,d;
                cin>>a>>b>>c>>d;
                if(len[a][b]>c)
                len[a][b]=len[b][a]=c;
                  if(cost[a][b]>d)
                cost[a][b]=cost[b][a]=d;
            }
            prim();
            int ans=0;
            for(int i=1;i<=n;i++){
                ans+=pre[i];
            }
            cout<<ans<<endl;
            
        }
    }
    View Code

    6.POJ - 3259

    要判断是否有负的权值

    #include<iostream>
    #include<stdio.h>
    #include<algorithm>
    #include<string.h>
    using namespace std;
    int map[550][550],n,m,k;
    int ff()
    {
        for(int k=1;k<=n;k++)
        {
            for(int i=1;i<=n;i++)
            {
                for(int j=1;j<=n;j++)
                {
                    int tt=map[i][k]+map[k][j];
                    if(map[i][j]>tt) map[i][j]=tt;
                }
                if(map[i][i]<0) return 1;
            }
         } 
         return 0;
    }
    int main()
    {
        int t;
        scanf("%d",&t);
        while(t--)
        {
            scanf("%d%d%d",&n,&m,&k);
            for(int i=1;i<=n;i++)
            {
                for(int j=1;j<=n;j++)
                {
                    if(i==j) map[i][j]=0;
                    else map[i][j]=0x3f3f3f3f;
                }
            }
            for(int i=1;i<=m;i++)
            {
                int a,b,c;
                scanf("%d%d%d",&a,&b,&c);
                if(c<map[a][b]) map[a][b]=map[b][a]=c;
            }
            for(int i=1;i<=k;i++)
            {
                int a,b,c;
                scanf("%d%d%d",&a,&b,&c);
                map[a][b]=-c; 
            }
            
            if(ff()) cout<<"YES"<<endl;
            else cout<<"NO"<<endl;
        }
        return 0;
    }
    View Code
  • 相关阅读:
    JQuery源码解析-Dom加载过程
    多个script标签的作用域
    JQuery源码解析-JQuery的工具方法(1)
    JQuery源码解析-JQuery的工具方法
    JQuery源码解析-JQuery.extend()方法
    JQuery源码解析-添加JQuery的一些方法和属性
    中兴捧月算法精英挑战赛-迪杰斯特拉派
    C语言中的内存相关问题
    动态内存管理
    虚函数与虚继承小结
  • 原文地址:https://www.cnblogs.com/wpbing/p/9336538.html
Copyright © 2011-2022 走看看