zoukankan      html  css  js  c++  java
  • 图论练习们~

    /*
     hdu 1599 ( find the mincost route )  
    Floyed求最小环
    每个环一定是 由 i j k 构成
    假设k是环中的max 要成环 就要保证不是链(md废话) 
    利用Floyed的最外层循环含义 i-j最短路经过的点编号<k 
    那个我们在 限制i<j<k 那么f[i][j]+g[i][k]+g[k][j]
    一定能构成一个环 并且点数>=3 因为i j k 互不相同 
    */
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #define maxn 110
    #define inf 2000000
    using namespace std;
    int n,m,f[maxn][maxn],g[maxn][maxn],ans;
    void Clear(){
        for(int i=0;i<=n;i++)
            for(int j=0;j<=n;j++)
                f[i][j]=g[i][j]=inf;
        ans=inf;
    }
    int min(int x,int y){
        return x<y?x:y;
    }
    void Floyed(){
        for(int k=1;k<=n;k++){
            for(int i=1;i<k;i++)
                for(int j=i+1;j<k;j++)
                    ans=min(ans,f[i][j]+g[i][k]+g[k][j]);
            for(int i=1;i<=n;i++)
                for(int j=1;j<=n;j++)
                    f[i][j]=min(f[i][j],f[i][k]+f[k][j]);
        }
    }
    int main()
    {
        while(~scanf("%d%d",&n,&m)){
            Clear();int u,v,t;
            for(int i=1;i<=m;i++){
                scanf("%d%d%d",&u,&v,&t);
                f[u][v]=min(f[u][v],t);
                f[v][u]=min(f[v][u],t);
                g[u][v]=g[v][u]=f[u][v];
            }
            Floyed();
            if(ans==inf)printf("It's impossible.
    ");
            else printf("%d
    ",ans);
        }
        return 0;
    }
    /*
    hdu 2807 ( The Shortest Path )  
    n*n判断矩阵相乘是不是等于另一矩阵
    比较快的矩阵比较方法 get了 
    */
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #define maxn 81
    #define inf 0x3f3f3f3f
    using namespace std;
    int n,m,Q,A[maxn][maxn],f[maxn][maxn],B[maxn];
    struct node{
        int c[maxn][maxn];
    }p[maxn];
    void Clear(){
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
                A[i][j]=0;
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
                f[i][j]=inf;    
    }
    void Insert(int x,int y){
        for(int i=1;i<=m;i++)B[i]=0;
        for(int i=1;i<=m;i++)
            for(int j=1;j<=m;j++)
                B[i]+=p[x].c[i][j]*A[y][j];
        int falg=0;
        for(int k=1;k<=n;k++){
            if(k==x||k==y)continue;
            falg=0;
            for(int i=1;i<=m;i++)
                if(A[k][i]!=B[i]){
                    falg=1;break;
                }
            if(!falg)f[x][k]=1;
        }
    }
    void Floyed(){
        for(int k=1;k<=n;k++)
            for(int i=1;i<=n;i++)
                for(int j=1;j<=n;j++)
                    f[i][j]=min(f[i][j],f[i][k]+f[k][j]);
    }
    int main()
    {
        while(1){
            scanf("%d%d",&n,&m);
            if(n==0&&m==0)break;
            Clear();int u,v;
            for(int k=1;k<=n;k++)
                for(int i=1;i<=m;i++)
                    for(int j=1;j<=m;j++){
                        scanf("%d",&p[k].c[i][j]);
                        A[k][i]+=p[k].c[i][j]*j;
                    }
            for(int i=1;i<=n;i++)
                for(int j=1;j<=n;j++)
                    Insert(i,j);
            Floyed();
            scanf("%d",&Q);
            while(Q--){
                scanf("%d%d",&u,&v);
                if(f[u][v]==inf)printf("Sorry
    ");
                else printf("%d
    ",f[u][v]);
            }
        }
        return 0;
    }
    /*
     hdu 2224 ( The shortest path ) 
    不知道为啥出现在最短路分类里 我纯dp做的 
    */
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #define maxn 210
    #define inf 0x3f3f3f3f
    using namespace std;
    int n;
    double x[maxn],y[maxn],g[maxn][maxn],f[maxn][maxn],ans;
    struct point{
        double x,y;
    }p[maxn];
    int cmp(const point &a,const point &b){
        return a.x<b.x;
    }
    void Clear(){
        for(int i=0;i<=n;i++)
            for(int j=0;j<=n;j++)
                f[i][j]=inf;
        for(int i=0;i<=n;i++)
            for(int j=0;j<=n;j++)
                g[i][j]=inf;
        ans=inf;
    }
    double Get(int i,int j){
        return sqrt((p[i].x-p[j].x)*(p[i].x-p[j].x)+(p[i].y-p[j].y)*(p[i].y-p[j].y));
    }
    int max(int a,int b){
        return a>b?a:b;
    }
    int main()
    {
        while(scanf("%d",&n)!=EOF){
            Clear();
            for(int i=1;i<=n;i++)
                scanf("%lf%lf",&p[i].x,&p[i].y);
            sort(p+1,p+1+n,cmp);
            for(int i=1;i<=n;i++)
                for(int j=i+1;j<=n;j++)
                    g[i][j]=g[j][i]=Get(i,j);
            f[1][1]=0;
            for(int i=1;i<=n;i++)
                for(int j=1;j<=n;j++){
                    int k=max(i,j)+1;
                    f[i][k]=min(f[i][k],f[i][j]+g[j][k]);
                    f[k][j]=min(f[k][j],f[i][j]+g[i][k]);
                }
            for(int i=1;i<=n;i++){
                ans=min(ans,f[i][n]+g[i][n]);
                ans=min(ans,f[n][i]+g[n][i]);
            }
            printf("%.2f
    ",ans);
        }
        return 0;
        
    }
    /*
    hdu  1598 ( find the most comfortable road )   
    再次被分类坑了...
    是并茶几不是最短路..
    枚举每组数据所用的最小的边-最大的边
    有点慢 不过还好并茶几飞快 
    */
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define maxn 1010
    using namespace std;
    int n,m,Q,fa[maxn],mx;
    struct node{
        int u,v,t;
        bool operator < (const node &a) const {
            return t<a.t;
        }
    }e[maxn];
    int init(){
        int x=0,f=1;char s=getchar();
        while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
        while(s>='0'&&s<='9'){x=x*10+s-'0';s=getchar();}
        return x*f;
    }
    int find(int x){
        if(x!=fa[x])fa[x]=find(fa[x]);
        return fa[x];
    }
    int min(int x,int y){
        return x<y?x:y;
    }
    int main()
    {
        while(~scanf("%d%d",&n,&m)){
            int u,v,t;
            for(int i=1;i<=m;i++){
                u=init();v=init();t=init();
                e[i].u=u;e[i].v=v;e[i].t=t;
            }
            sort(e+1,e+1+m);
            Q=init();
            while(Q--){
                u=init();v=init();mx=0x7fffffff;
                for(int k=1;k<=m;k++){
                    for(int i=1;i<=n;i++)fa[i]=i;
                    for(int i=k;i<=m;i++){
                        int r1=find(e[i].u);
                        int r2=find(e[i].v);
                        if(r1!=r2)fa[r2]=r1;
                        if(find(u)==find(v)){
                            mx=min(mx,e[i].t-e[k].t);break;
                        }
                    }
                }
                if(mx==0x7fffffff)printf("-1
    ");
                else printf("%d
    ",mx);
            }
        }
        return 0;
    }
    /*+几条边不存在桥*/
    #include<iostream>
    #include<cstdio>
    #include<stack>
    #include<cstring>
    #define maxn 1010
    using namespace std;
    int n,m,num,head[maxn],low[maxn],dfn[maxn],topt,f[maxn],r[maxn],sum,belong[maxn];
    stack<int>s;
    struct node{
        int v,pre;
    }e[maxn*2];
    int init(){
        int x=0,f=1;char s=getchar();
        while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
        while(s>='0'&&s<='9'){x=x*10+s-'0';s=getchar();}
        return x*f;
    }
    void Clear(){
        num=0;topt=0;sum=0;
        for(int i=0;i<=n;i++)f[i]=0;
        for(int i=0;i<=n;i++)r[i]=0;
        for(int i=0;i<=n;i++)low[i]=0;
        for(int i=0;i<=n;i++)dfn[i]=0;
        for(int i=0;i<=n;i++)head[i]=-1;
        for(int i=0;i<=n;i++)belong[i]=0;
        while(!s.empty())s.pop();
    }
    void Add(int from,int to){
        e[num].v=to;
        e[num].pre=head[from];
        head[from]=num++;
    }
    void Dfs(int x,int from){
        low[x]=dfn[x]=++topt;
        f[x]=1;s.push(x);
        for(int i=head[x];i!=-1;i=e[i].pre){
            int v=e[i].v;
            if(i==(from^1))continue;
            if(dfn[v]==0){
                Dfs(v,i);low[x]=min(low[x],low[v]);
            }
            else if(f[v])low[x]=min(low[x],dfn[v]);
        }
        if(low[x]==dfn[x]){
            sum++;
            while(s.top()!=x){
                belong[s.top()]=sum;f[s.top()]=0;s.pop();
            }
            belong[s.top()]=sum;f[s.top()]=0;s.pop();
        }
    }
    int main()
    {
        while(~scanf("%d%d",&n,&m)){
            Clear();int u,v;
            for(int i=1;i<=m;i++){
                u=init();v=init();
                Add(u,v);Add(v,u);
            }
            for(int i=1;i<=n;i++)
                if(dfn[i]==0)Dfs(i,-1);
            for(int u=1;u<=n;u++)
                for(int i=head[u];i!=-1;i=e[i].pre){
                    int v=e[i].v;
                    if(belong[u]!=belong[v])r[belong[u]]++;
                }
            int cnt=0;
            for(int i=1;i<=sum;i++)
                if(r[i]==1)cnt++;
            printf("%d
    ",(cnt+1)/2);
        }
        return 0;
    }
    /*hdu 3768 ( Shopping )   SPFA+全排列*/
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    #define maxn 200010
    using namespace std;
    int T,n,m,k,c[20],num,head[maxn],dis[maxn],g[20][20],f[maxn],a[20];
    long long ans;
    struct node{
        int v,t,pre;
    }e[maxn*10];
    queue<int>q;
    int init(){
        int x=0,f=1;char s=getchar();
        while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
        while(s>='0'&&s<='9'){x=x*10+s-'0';s=getchar();}
        return x*f;
    }
    void Clear(){
        num=0;ans=0x7fffffff;
        memset(head,0,sizeof(head));
        memset(g,127/3,sizeof(g));
        memset(a,0,sizeof(a));
        memset(c,0,sizeof(c));
    }
    void Add(int from,int to,int dis){
        num++;e[num].v=to;
        e[num].t=dis;
        e[num].pre=head[from];
        head[from]=num;
    }
    void SPFA(int s){
        memset(dis,127/3,sizeof(dis));
        memset(f,0,sizeof(f));
        dis[s]=0;f[s]=1;q.push(s);
        while(!q.empty()){
            int u=q.front();
            f[u]=0;q.pop();
            for(int i=head[u];i;i=e[i].pre){
                int v=e[i].v;
                if(dis[v]>dis[u]+e[i].t){
                    dis[v]=dis[u]+e[i].t;
                    if(f[v]==0){
                        f[v]=1;q.push(v);
                    }
                }
            }
        }
    }
    int main()
    {
        T=init();
        while(T--){
            n=init();m=init();
            Clear();int u,v,t;
            for(int i=1;i<=m;i++){
                u=init();v=init();t=init();
                Add(u,v,t);Add(v,u,t);
            }
            k=init();
            for(int i=1;i<=k;i++){
                c[i]=init();a[i]=i;
            }
            SPFA(0);
            for(int i=1;i<=k;i++)
                g[0][i]=g[i][0]=dis[c[i]];
            for(int i=1;i<=k;i++){
                SPFA(c[i]);
                for(int j=1;j<=k;j++)
                    g[i][j]=dis[c[j]];
            }
            do{
                long long mx=0;
                for(int i=1;i<=k+1;i++)
                    mx+=g[a[i-1]][a[i]];
                ans=min(ans,mx);
            }while(next_permutation(a+1,a+k+1));
            cout<<ans<<endl;
        }
        return 0;
    }
    /*poj 1679 次小生成树n*n算法 get了*/
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define maxn 110
    using namespace std;
    int T,n,m,num,head[maxn],fa[maxn],c[maxn*maxn],mx[maxn][maxn],mst,ans;
    struct node{
        int u,v,t,o;
        bool operator < (const node &x) const{
            return t<x.t;
        }
    }p[maxn*maxn];
    struct edge{
        int v,t,pre,x;
    }e[maxn*maxn*2];
    void Clear(){
        num=mst=0;ans=0x7fffffff;
        for(int i=0;i<=n;i++)fa[i]=i;
        for(int i=0;i<=n;i++)
            for(int j=0;j<=n;j++)
                mx[i][j]=0;
        for(int i=0;i<=m;i++)c[i]=0;
        for(int i=0;i<=n;i++)head[i]=0;
    }
    void Add(int from,int to,int dis,int numb){
        num++;e[num].v=to;
        e[num].t=dis;
        e[num].x=numb;
        e[num].pre=head[from];
        head[from]=num;
    }
    int find(int x){
        if(x!=fa[x])fa[x]=find(fa[x]);
        return fa[x];
    }
    void MST(){
        int tot=0;
        for(int i=1;i<=m;i++){
            int r1=find(p[i].u);
            int r2=find(p[i].v);
            if(r1!=r2){
                tot++;mst+=p[i].t;
                c[p[i].o]=1;fa[r2]=r1;
            }
            if(tot==n-1)break;
        }
    }
    void Dfs(int s,int now,int from,int mxx){
        mx[s][now]=mxx;
        for(int i=head[now];i;i=e[i].pre){
            int v=e[i].v;
            if(v==from)continue;
            if(c[e[i].x]==0)continue;
            Dfs(s,v,now,max(mxx,e[i].t));
        }
    }
    void Mx(){
        for(int i=1;i<=n;i++)
            Dfs(i,i,-1,0);
    }
    int main()
    {
        scanf("%d",&T);
        while(T--){
            scanf("%d%d",&n,&m);
            Clear();int u,v,t;
            for(int i=1;i<=m;i++){
                scanf("%d%d%d",&u,&v,&t);
                Add(u,v,t,i);Add(v,u,t,i);
                p[i].u=u;p[i].v=v;
                p[i].t=t;p[i].o=i;
            }
            sort(p+1,p+1+m);
            MST();Mx();
            for(int i=1;i<=m;i++){
                if(c[p[i].o])continue;
                int len=mx[p[i].u][p[i].v];
                ans=min(ans,mst+p[i].t-len);
            }
            if(ans==mst)printf("Not Unique!
    ");
            else printf("%d
    ",mst);
        }
        return 0;
    }
  • 相关阅读:
    单例实现c++
    c++智能指针实现方式1
    c++中处理输入输出的方法
    makefile函数
    5. Longest Palindromic Substring
    go 语言中常用的包
    ubuntu14.04 boost动态库找不到 libboost_system.so.1.58.0
    boost-asio-cpp-network-programming阅读笔记
    链接-装载-库,读书笔记
    leecode第二百一十七题(存在重复元素)
  • 原文地址:https://www.cnblogs.com/yanlifneg/p/5962315.html
Copyright © 2011-2022 走看看