第11章 图论模型与算法

再谈树

无根树转有根数

#include<bits/stdc++.h>
using namespace std;
const int maxn = 100;
vector<int> G[maxn];
int n;
void read_tree(){
    int u,v;
    scanf("%d",&n);
    for(int i=0;i<n-1;i++){
        scanf("%d%d",&u,&v);
        G[u].push_back(v);
        G[v].push_back(u);
    }
}
int p[100];
void dfs(int u,int fa){//转化为u为根的子树,u的父结点为fa

    int d=G[u].size();
    for(int i=0;i<d;i++){
        int v=G[u][i];
        if(v!=fa) dfs(v,p[v]=u);
    }
}
int main()
{
    read_tree();
    for(int i=0;i<n-1;i++){ printf("%d:",i);
        for(int j=0;j<G[i].size();j++)
        printf("%d ",G[i][j]);
        printf("\n");
    }
    p[1]=-1;
    dfs(1,-1);
    for(int i=0;i<n;i++) printf("%d ",i); printf("\n");<pre name="code" class="cpp">const int maxn = 100;
int lch[maxn], rch[maxn]; char op[maxn]; //每个结点的左右子节点编号和字符
int nc=0; //结点数
int build_tree(char * s,int x,int y){
    int i,c1=-1,c2=-1,p=0;
    int u;
    if(y-x==1) { //进一个字符建立单独结点
        u = ++nc;
        lch[u]=rch[u]=0; op[u]=s[x];
        return u;
    }
    for(i=x;i<y;i++){
        switch(s[i]){
            case '(':p++;break;
            case ')':p--;break;
            case '+':case '-': if(!p) c1=i; break;
            case '*':case '/': if(!p) c2=i; break;
        }
    }
    if(c1<0) c1=c2;
    if(c1<0) return build_tree(s,x+1,y-1);
    u=++nc;
    lch[u]=build_tree(s,x,c1);
    ech[u]=build_tree(s,c1+1,y);
    op[u]=s[c1];
    return u;
}

for(int i=0;i<n;i++) printf("%d ",p[i]); printf("\n"); /* 初始的树 8 1 4 1 5 1 0 5 6 5 7 0 2 0 3 0:1 2 3 1:4 5 0 2:0 3:0 4:1 5:1 6 7 6:5 */ return 0;}


表达式树

const int maxn = 100;
int lch[maxn], rch[maxn]; char op[maxn]; //每个结点的左右子节点编号和字符
int nc=0; //结点数
int build_tree(char * s,int x,int y){
    int i,c1=-1,c2=-1,p=0;
    int u;
    if(y-x==1) { //进一个字符建立单独结点
        u = ++nc;
        lch[u]=rch[u]=0; op[u]=s[x];
        return u;
    }
    for(i=x;i<y;i++){
        switch(s[i]){
            case '(':p++;break;
            case ')':p--;break;
            case '+':case '-': if(!p) c1=i; break;
            case '*':case '/': if(!p) c2=i; break;
        }
    }
    if(c1<0) c1=c2;
    if(c1<0) return build_tree(s,x+1,y-1);
    u=++nc;
    lch[u]=build_tree(s,x,c1);
    ech[u]=build_tree(s,c1+1,y);
    op[u]=s[c1];
    return u;
}

例题11-1 公共表达式消除  uva12219

#include<bits/stdc++.h>
using namespace std;
const int INF = 0x3f3f3f3f;
const int MAXN = 105;
struct Edge {
    int u,v,cost;
    bool operator < (const Edge& a) const {
        return cost > a.cost;
    }
};
int F[MAXN];int n,m;vector<Edge> edges;
int find(int x){
    return x==F[x]?x:F[x]=find(F[x]);
}
int kruskal(int k){
    for(int i=0;i<=n;i++) F[i]=i;
    int cnt=0;
    int minn=INF,maxn=0;
    for(int i=k;i<m;i++)
    {
        Edge e = edges[i];
        int v=e.v;
        int u=e.u;
        int fu=find(u);
        int fv=find(v);
        if(fu!=fv){
            cnt++;
            F[fu]=fv;
            minn=min(e.cost,minn);
            maxn =max(e.cost,maxn);
        }
    }
    if(cnt!=n-1)return -1;
    else return maxn-minn;
}

int main()
{
    while(~scanf("%d%d",&n,&m)){
        if(n==0&&m==0) break;
        edges.clear();
        for(int i=1;i<=m;i++){
            int a,b,c;
            scanf("%d%d%d",&a,&b,&c);
            edges.push_back((Edge){a,b,c} );
        }
        sort(edges.begin(),edges.end());
        int ans=INF;
        for(int i=0;i<=m;i++){
            int t=kruskal(i);
            if(t==-1) break;
            ans = min(ans,t);
        }
        if(ans == INF) printf("%d\n",-1);
        else printf("%d\n",ans);
    }
    return 0;
}

例题11-3 买还是建 uva1151

#include<bits/stdc++.h>
using namespace std;
const int maxn = 1005;
struct point {
    int x,y;
}pp[maxn];
struct edge
{
    int s,e,dist;
}l[maxn*maxn];
int n,q,m;
int p[maxn];
vector<int> g[10];
int c[10];
int distance_(point a,point b){
    return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);
}
bool cmp(edge a,edge b){
    return a.dist < b.dist;
}
int find_(int x){
    return p[x]==x?x:p[x]=find_(p[x]);
}
bool merge_(int a,int b){
    int x=find_(a);
    int y=find_(b);
    if(x==y) return false;
    p[x]=y; return true;
}
int kruskal(){
    int ans=0;
    int num=0;
    for(int i=0;i<m&&num<n-1;i++)
    {
        if(merge_(l[i].s,l[i].e))
        {
            num++;
            ans += l[i].dist;
        }
    }
    return ans;
}
void solve(){
    for(int i=0;i<=n;i++) p[i]=i;
    int ans=kruskal();
    for(int s=1;s<(1<<q);s++){
        int cost=0;
        for(int tt=0;tt<=n;tt++) p[tt]=tt;
        for(int j=0;j<q;j++){
            if(!((s>>j)&1)) continue;
            cost += c[j];
            for(int k=0;k<g[j].size();k++)
            {
                merge_(g[j][k],g[j][0]);
            }
        }
        ans =min(ans, cost+kruskal());
    }
    printf("%d\n",ans);
}
int main()
{
    int t;
    scanf("%d",&t);
    while(t--){
        scanf("%d%d",&n,&q);
        for(int i=0;i<10;i++) g[i].clear();
        for(int i=0;i<q;i++){
            int cnt;
            scanf("%d%d",&cnt,&c[i]);
            int a;
            for(int j=0;j<cnt;j++){
                scanf("%d",&a);
                g[i].push_back(a);
            }
        }
        for(int i=1;i<=n;i++){
            scanf("%d%d",&pp[i].x,&pp[i].y);
        }
        m=0;
        for(int i=1;i<=n;i++)
        {
            for(int j=i+1;j<=n;j++)
            {
                l[m].s=i;
                l[m].e=j;
                l[m++].dist=distance_(pp[i],pp[j]);
            }
        }
        sort(l,l+m,cmp);
        solve();
        if(t) printf("\n");
    }
    return 0;
}

Dijkstra算法:

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-11-05 13:39:56

第11章 图论模型与算法的相关文章

html学习第三天—— 第11章 盒子模型 div

盒模型--边框(一) 盒子模型的边框就是围绕着内容及补白的线,这条线你可以设置它的粗细.样式和颜色(边框三个属性). 如下面代码为div来设置边框粗细为2px.样式为实心的.颜色为红色的边框: div{ border:2px solid red; } 上面是border代码的缩写形式,可以分开写: div{ border-width:2px; border-style:solid; border-color:red; } 注意: 1.border-style(边框样式)常见样式有: dashed

图论模型---floyd算法

1.目标:最优路线规划. 2.Matlab程序: tulun2.m a= [ 0,50,inf,40,25,10; 50,0,15,20,inf,25; inf,15,0,10,20,inf; 40,20,10,0,10,25; 25,inf,20,10,0,55; 10,25,inf,25,55,0]; [D, path]=floyd(a) floyd.m function [D,path,min1,path1]=floyd(a,start,terminal) D=a;n=size(D,1);

C++ Primer 读书笔记:第11章 泛型算法

第11章 泛型算法 1.概述 泛型算法依赖于迭代器,而不是依赖容器,需要指定作用的区间,即[开始,结束),表示的区间,如上所示 此外还需要元素是可比的,如果元素本身是不可比的,那么可以自己定义比较函数. 2.常用的泛型算法函数: fill,fill_n, copy, replace, sort, unique, count_if, stable_sort 此外在有一个谓词函数会结合以上的函数使用,像sort, count_if等 3.再谈迭代器 (1)插入迭代器 back_inserter, f

各种图论模型及其解答(转载)

原文转自Jelline blog http://blog.chinaunix.net/uid-9112803-id-411340.html //============================== 在做研究的过程中,发现其实以前觉得没什么用的数学模型或者图论模型,突然间变得非常有用起来.感叹于自己相关知识的不足,于是搜索相关知识进行学习,并分享. 这篇转载的文章对于从事网络方向研究的初级人员有一定帮助,譬如我.对于已经熟悉图论各模型.各细节的人可以直接关闭此网页离开. //=======

各种图论模型及其解答(转)

原文转自Jelline blog http://blog.chinaunix.net/uid-9112803-id-411340.html 摘要: 本文用另一种思路重新组织<图论及其应用>相关知识.首先,用通俗化语言阐述了如何对事物间联系的问题进行图论建模:接着从现实例子出发,给出 各种典型图论模型,每种图论模型对应于图论一个重要内容:再者,介绍相关知识对上述提到的图论模型涉及的问题进行解答:最后,补充一些图论其他知识,包括 图论分支.易混概念. 符号约定: Q(Question)表示对问题描

统计学习方法 李航---第11章 条件随机场

第11章 条件随机场 条件随机场(conditional random field, CRF)是给定一组输入随机变量条件下另一组输出随机变量的条件概率分布模型,其特点是假设输出随机变量构成马尔可夫随机场.条件随机场可以用于不同的预测问题,本章主要讲述线性链(linear chain)条件随机场在标注问题的应用,这时问题变成了由输入序列对输出序列预测的判别模型,形式为对数线性模型,其学习方法通常是极大似然估计或正则化的极大似然估计. 11.1 概率无向图模型 概率无向图模型(probabilist

《数据结构与算法分析:C语言描述》复习——第九章“图论”——无权值的最短路径问题

2014.07.04 18:24 简介: 给定一个有向图,你可以认为每条边长度都是1(所以叫无权值).下面的算法可以求出从特定的起点到终点的最短路径长度. 描述: 从起点出发,根据当前顶点出发的边进行广度优先搜索,直至找到终点即可.如果搜索结束了仍然没有找到终点,那么起点无法到达终点. 实现: 1 // A simple illustration for unweighted shortest path. Graph represented by adjacency matrix. 2 #inc

敏捷软件开发:原则、模式与实践——第11章 DIP:依赖倒置原则

第11章 DIP:依赖倒置原则 DIP:依赖倒置原则: a.高层模块不应该依赖于低层模块.二者都应该依赖于抽象. b.抽象不应该依赖于细节.细节应该依赖于抽象. 11.1 层次化 下图展示了一个简单的层次化方案: 高层的Policy层使用了低层的Mechanism层,而Mechanism层又使用了更细节的Utility层.它存在一个隐伏的错误特征,那就是:Policy层对于其下一直到Utility层的改动都是敏感的.依赖关系是传递的. 下图展示了一个更为合适的模型: 每个较高层次都为它所需要的服

《白帽子讲WEB安全》学习笔记之第11章 加密算法与随机数

第11章 加密算法与随机数 11.1 概述 攻击密码系统的方法 密码分析者攻击密码系统的方法主要有以下三种: (1)穷举攻击 所谓穷举攻击是指密码分析者采用依次试遍所有可能的密钥对所获密文进行解密,直至得到正确的明文. (2)统计分析攻击 所谓统计分析攻击就是指密码分析者通过分析密文和明文的统计规律来破译密码. (3)数学分析攻击 所谓数学分析攻击是指密码分析者针对加解密算法的数学基础和某些密码学特性,通过数学求解的方法来破译密码. 破译密码的类型 (1)唯密文攻击(Ciphertext-onl