zoukankan      html  css  js  c++  java
  • 模板 图论

    存图

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cstring>
     4 #include<queue>
     5 using namespace std;
     6 const int Maxv=1000;
     7 struct node{
     8     int v;
     9     node* next;
    10 };
    11 int n,e;
    12 typedef node* link;
    13 link g[Maxv];
    14 bool visited[Maxv];
    15 queue<int> q;
    16 void Insert(int u,int v){//insert edge(u,v) to  Adjacency list
    17     link x;
    18     x=new node;
    19     x->v=v;x->next=g[u];g[u]=x;
    20 }
    21 void init(){
    22     int u,v;
    23     cin>>n>>e;
    24     memset(visited,0,sizeof(visited));
    25     memset(g,0,sizeof(g));
    26     for(int i=0;i<e;i++){
    27         cin>>u>>v;
    28         Insert(u,v);
    29         Insert(v,u);
    30     }
    31     return ;
    32 }
    33 void BFS(int v){
    34     cout<<v<<" ";
    35     visited[v]=1;
    36     q.push(v);
    37     while(!q.empty()){
    38         int i=q.front();
    39         q.pop();
    40         for(link x=g[i];x!=NULL;x=x->next){
    41             int u=x->v;
    42             if(!visited[u]){
    43                 cout<<u<<" ";
    44                 visited[u]=1;
    45                 q.push(u);
    46             }
    47         }
    48     }
    49 }
    50 int main(){
    51     init();
    52     memset(visited,0,sizeof(visited));
    53     for(int i=1;i<=n;i++) if(!visited[i]) {
    54         BFS(i);
    55         cout<<endl;
    56     }
    57     return 0;
    58 }
    59 /*******************************************************/
    60 void DFS(int v){
    61     cout<<v<<" ";
    62     visited[v]=1;
    63     for(link x=g[v];x!=NULL;x=x->next){
    64         int u=x->v;
    65         if(!visited[u]) DFS(u);
    66     } 
    67 }
    68 int main(){
    69     init();
    70     for(int i=1;i<=n;i++) if(!visited[i]){
    71         DFS(i);
    72         cout<<endl;
    73     } 
    74     
    75 }
    Adjacency list(邻接链表)
      1 #include<iostream>
      2 #include<queue>
      3 #include<stack>
      4 #include<stdlib.h>
      5 #define MAX 100
      6 using namespace std;
      7 
      8 typedef struct 
      9 {
     10     int edges[MAX][MAX];    //邻接矩阵
     11     int n;                  //顶点数
     12     int e;                  //边数
     13 }MGraph;
     14 
     15 bool visited[MAX];          //标记顶点是否被访问过
     16 
     17 void creatMGraph(MGraph &G)    //用引用作参数
     18 {
     19     int i,j;
     20     int s,t;                 //存储顶点编号
     21     int v;                   //存储边的权值
     22     for(i=0;i<G.n;i++)       //初始化
     23     {
     24         for(j=0;j<G.n;j++)
     25         {
     26             G.edges[i][j]=0;
     27         }
     28         visited[i]=false;
     29     }
     30     for(i=0;i<G.e;i++)      //对矩阵相邻的边赋权值
     31     {
     32         scanf("%d %d %d",&s,&t,&v);   //输入边的顶点编号以及权值
     33         G.edges[s][t]=v;
     34     }
     35 }
     36 
     37 void DFS(MGraph G,int v)      //深度优先搜索
     38 {
     39     int i;
     40     printf("%d ",v);          //访问结点v
     41     visited[v]=true;
     42     for(i=0;i<G.n;i++)       //访问与v相邻的未被访问过的结点
     43     {
     44         if(G.edges[v][i]!=0&&visited[i]==false)
     45         {
     46             DFS(G,i);
     47         }
     48     }
     49 }
     50 
     51 void DFS1(MGraph G,int v)   //非递归实现
     52 {
     53     stack<int> s;
     54     printf("%d ",v);        //访问初始结点
     55     visited[v]=true;
     56     s.push(v);              //入栈
     57     while(!s.empty())
     58     {
     59         int i,j;
     60         i=s.top();          //取栈顶顶点
     61         for(j=0;j<G.n;j++)  //访问与顶点i相邻的顶点
     62         {
     63             if(G.edges[i][j]!=0&&visited[j]==false)
     64             {
     65                 printf("%d ",j);     //访问
     66                 visited[j]=true;
     67                 s.push(j);           //访问完后入栈
     68                 break;               //找到一个相邻未访问的顶点,访问之后则跳出循环
     69             }
     70         }
     71         if(j==G.n)                   //如果与i相邻的顶点都被访问过,则将顶点i出栈
     72             s.pop();
     73     }
     74 }
     75 
     76 void BFS(MGraph G,int v)      //广度优先搜索
     77 {
     78     queue<int> Q;             //STL模板中的queue
     79     printf("%d ",v);
     80     visited[v]=true;
     81     Q.push(v);
     82     while(!Q.empty()) 
     83     {
     84         int i,j;
     85         i=Q.front();         //取队首顶点
     86         Q.pop();
     87         for(j=0;j<G.n;j++)   //广度遍历
     88         {
     89             if(G.edges[i][j]!=0&&visited[j]==false)
     90             {
     91                 printf("%d ",j);
     92                 visited[j]=true;
     93                 Q.push(j);
     94             }
     95         }
     96     }
     97 }
     98 
     99 int main(void)
    100 {
    101     int n,e;    //建立的图的顶点数和边数
    102     while(scanf("%d %d",&n,&e)==2&&n>0)
    103     {
    104         MGraph G;
    105         G.n=n;
    106         G.e=e;
    107         creatMGraph(G);
    108         DFS(G,0);
    109         printf("
    ");
    110     //    DFS1(G,0);
    111     //    printf("
    ");
    112     //    BFS(G,0);
    113     //    printf("
    ");
    114     }
    115     return 0;
    116 }
    createMGraph(邻接矩阵)
      1 #define MAX_VERTEX_NUM 20  
      2 #include<iostream>  
      3 #include<string>  
      4 using namespace std;  
      5   
      6 template<class T>  
      7 int Locate_Vex(T G,string x) //定位顶点位置  
      8 {  
      9     for(int k=0;G.vexs[k]!=x;k++);  
     10     return k;  
     11 }  
     12   
     13 //邻接矩阵存储图  
     14 struct MGraph  
     15 {  
     16     string vexs[MAX_VERTEX_NUM];//顶点数组  
     17     int arcs[MAX_VERTEX_NUM][MAX_VERTEX_NUM]; //邻接矩阵  
     18     int vexnum;//顶点数目  
     19     int arcnum;//边数目  
     20 };  
     21   
     22 void CreateUDN_MG(MGraph &G)  
     23 {  
     24     //采用邻接矩阵表示法,构造无向网  
     25     cin>>G.vexnum>>G.arcnum;  
     26     for(int i=0;i<G.vexnum;i++)  
     27         cin>>vaxs[i];  
     28       
     29     for(i=0;i<G.vexnum;i++)  
     30         for(int j=0;j<G.vexnum;j++)  
     31             G.arcs[i][j]=-1;  
     32     //上面是初始化邻接矩阵,-1表示两点间边的权值为无穷大  
     33       
     34     for(int k=0;k<G.arcnum;k++)  
     35     {  
     36         string v1,v2;  
     37         int w;  
     38         cin>>v1>>v2>>w;  
     39         i=Locate_Vex(G,v1);  
     40         j=Locate_Vex(G,v2);  
     41         while(i<0|| i>G.vexnum-1 || j<0 || j>G.vexnum-1)  
     42         {  
     43             cout<<"结点位置输入错误,重新输入: ";  
     44             cin>>v1>>v2>>w;  
     45             i=Locate_Vex(G,v1);  
     46             j=Locate_Vex(G,v2);   
     47         }  
     48         G.arcs[i][j]=w;  
     49         G.arcs[j][i]=G.arcs[i][j]; //置对称边  
     50     }  
     51 }  
     52   
     53 //邻接表存储图  
     54 //表结点  
     55 struct ArcNode  
     56 {  
     57     int adjvex; //弧所指向顶点的位置  
     58     ArcNode *nextarc;// 指向下一条弧  
     59 };  
     60   
     61 //头结点  
     62 typedef struct VNode  
     63 {  
     64     string data;//顶点名  
     65     ArcNode *firstarc;//指向第一条关联顶点的弧  
     66 }AdjList[MAX_VERTEX_NUM];  
     67   
     68 struct ALGraph  
     69 {  
     70     AdjList vertices;//头结点数组  
     71     int vexnum;  
     72     int arcnum;  
     73 };  
     74   
     75 void CreateDG_ALG(ALGraph &G)  
     76 {  
     77     //采用邻接表存储表示,构造有向图G  
     78     string v1,v2;  
     79     int i,j,k;  
     80     cin>>G.arcnum>>G.vexnum;  
     81       
     82     //构造头结点数组  
     83     for(i=0;i<G.vexnum;i++)  
     84     {  
     85         cin>>G.vertices[i].data;  
     86         G.vertices[i].firstarc=NULL;  
     87     }  
     88   
     89     //输入各弧并构造邻接表  
     90     for(k=0;k<G.arcnum;k++)  
     91     {  
     92         cin>>v1>>v2;  
     93         i=Locate_Vex(G,v1);  
     94         j=Locate_Vex(G,v2);  
     95         while(i<0|| i>G.vexnum-1 || j<0 || j>G.vexnum-1)  
     96         {  
     97             cout<<"结点位置输入错误,重新输入: ";  
     98             cin>>v1>>v2;  
     99             i=Locate_Vex(G,v1);  
    100             j=Locate_Vex(G,v2);   
    101         }  
    102       
    103         ArcNode *p=new ArcNode;  
    104         p->adjvex=j;  
    105         p->nextarc=NULL;  
    106         p->nextarc=G.vertices[i].firstarc;  
    107         G.vertices[i].firstarc=p;  
    108     }  
    109 }  
    110   
    111 //十字链表方式存储有向图  
    112 //弧结点  
    113 struct ArcBox  
    114 {  
    115     int tailvex,headvex;//弧结点头尾结点位置  
    116     ArcBox *hlink,*tlink;//弧头和弧尾相同的弧的链域  
    117 };  
    118   
    119 //顶点结点  
    120 struct VexNode  
    121 {  
    122     string data;  
    123     ArcBox *firstin,*firstout;//顶点第一条入弧和出弧  
    124 };  
    125   
    126 struct OLGraph  
    127 {  
    128     VexNode xlist[MAX_VERTEX_NUM];  
    129     int vexnum;  
    130     int arcnum;  
    131 };  
    132   
    133 void CreateDG_OLG(OLGraph &G)  
    134 {  
    135     //采用十字链表存储表示,构造有向图G  
    136     string v1,v2;  
    137     int i,j,k;  
    138     cin>>G.vexnum>>G.arcnum;  
    139     for(i=0;i<G.vexnum;i++)  
    140     {  
    141         cin>>G.xlist[i].data;  
    142         G.xlist[i].firstin=NULL;  
    143         G.xlist[i].firstout=NULL;  
    144     }  
    145     for(k=0;k<G.arcnum;k++)  
    146     {  
    147         cin>>v1>>v2;  
    148         i=Locate_Vex(G,v1);  
    149         j=Locate_Vex(G,v2);  
    150       
    151         while(i<0|| i>G.vexnum-1 || j<0 || j>G.vexnum-1)  
    152         {  
    153             cout<<"结点位置输入错误,重新输入: ";  
    154             cin>>v1>>v2;  
    155             i=Locate_Vex(G,v1);  
    156             j=Locate_Vex(G,v2);   
    157         }         
    158   
    159         ArcBox *p=new ArcBox;  
    160         p->tailvex=i;  
    161         p->headvex=j;  
    162         p->hlink=G.xlist[j].firstin;  
    163         p->tlink=G.xlist[i].firstout;  
    164         G.xlist[i].firstout=G.xlist[j].firstin=p;  
    165     }  
    166 }  
    167           
    168 //邻接多重表存储  
    169 //边结点  
    170 struct EBox  
    171 {  
    172     int mark;//标志域,指示该边是否被访问过(0:没有 1:有)  
    173     int ivex,jvex;//该边关联的两个顶点的位置  
    174     EBox *ilink,*jlink;//分别指向关联这两个顶点的下一条边  
    175 };  
    176   
    177 //顶点结点  
    178 struct VexBox  
    179 {  
    180     string data;  
    181     EBox *firstedge;//指向第一条关联该结点的边  
    182 };  
    183   
    184 struct AMLGraph  
    185 {  
    186     VexBox adjmulist[MAX_VERTEX_NUM];  
    187     int vexnum;  
    188     int arcnum;  
    189 };  
    190   
    191 void CreateUDG_AML(AMLGraph &G)  
    192 {  
    193     //用邻接多重表存储,构造无向图G  
    194     string v1,v2;  
    195     int i,j,k;  
    196     cin>>G.vexnum>>G.arcnum;  
    197     for(i=0;i<G.vexnum;i++)  
    198     {  
    199         cin>>G.adjmulist[i].data;  
    200         G.adjmulist[i].firstedge=NULL;  
    201     }  
    202   
    203     for(k=0;k<G.arcnum;k++)  
    204     {  
    205         cin>>v1>>v2;  
    206         i=Locate_Vex(G,v1);  
    207         j=Locate_Vex(G,v2);  
    208           
    209         while(i<0|| i>G.vexnum-1 || j<0 || j>G.vexnum-1)  
    210         {  
    211             cout<<"结点位置输入错误,重新输入: ";  
    212             cin>>v1>>v2;  
    213             i=Locate_Vex(G,v1);  
    214             j=Locate_Vex(G,v2);   
    215         }  
    216   
    217         EBox *p=new EBox;  
    218         p->ivex=i;  
    219         p->jvex=j;  
    220         p->ilink=G.adjmulist[i].firstedge;  
    221         p->jlink=G.adjmulist[j].firstedge;  
    222         p->mark=0;  
    223         G.adjmulist[i].firstedge=G.adjmulist[j].firstedge=p;  
    224     }  
    225 }  
    不实用

    最短路

     1 #include<cstdio>
     2 #include<cstring>
     3 #define MAXN 1005
     4 using namespace std;
     5 int n,m,s;
     6 int d[MAXN][MAXN];
     7 inline int Min(int a,int b){return a<b?a:b;}
     8 inline void floyd(){
     9     for(int k=1;k<=n;k++)
    10         for(int i=1;i<=n;i++)
    11             for(int j=1;j<=n;j++){
    12                 d[i][j]=Min(d[i][j],d[i][k]+d[k][j]);
    13             }
    14 }
    15 int main(){
    16     //freopen("floyd.txt","r",stdin);
    17     scanf("%d%d%d",&n,&m,&s);
    18     for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) d[i][j]=0x3fffffff;
    19     for(int i=1;i<=m;i++) {
    20         int x,y,z;scanf("%d%d%d",&x,&y,&z); d[x][y]=Min(d[x][y],z);
    21     }
    22     for(int i=1;i<=n;i++) d[i][i]=0; 
    23     floyd();
    24     for(int i=1;i<=n;i++) printf("%d ",d[s][i]==0x3fffffff?2147483647:d[s][i]);
    25 }
    floyd
     1 #include<stdio.h>
     2 #include<string.h>
     3 #include<stdlib.h>
     4 #include<iostream>
     5 const int maxN=10005,maxM=500005;
     6 struct edge{int u,v,w;}e[maxM];
     7 int top=0,head[maxN],to[maxM],nxt[maxM],val[maxM];
     8 void add(int u,int v,int w){top++;to[top]=v,nxt[top]=head[u],val[top]=w;head[u]=top;}
     9 struct queue{
    10     int head,tail,data[maxM];
    11     queue(){head=1,tail=0;}
    12     void push(int x){data[tail=(tail+1)%maxM]=x;}
    13     void pop(){head=(head+1)%maxM;}
    14     int front(){return data[head];}
    15     bool empty(){return tail<head;}
    16 }q;
    17 int d[maxN];
    18 void defense(edge *buf,int len){
    19     srand(233333);
    20     for(int i=0;i<len;i++)
    21         std::swap(buf[rand()%len],buf[rand()%len]);
    22 }
    23 void spfa(int u){
    24     memset(d,0x3f,sizeof(d));
    25     d[u]=0; q.push(u);
    26     while(!q.empty()){
    27         int tmp=q.front(),now=head[tmp]; q.pop();
    28         while(now!=0){
    29             if(d[to[now]]>d[tmp]+val[now]){
    30                 d[to[now]]=d[tmp]+val[now];
    31                 q.push(to[now]);
    32             }
    33             now=nxt[now];
    34         }
    35     }
    36 }
    37 int main(){
    38 //    freopen("1.in","r",stdin);
    39     int n,s,t; scanf("%d%d%d",&n,&s,&t);
    40     for(int i=1;i<=s;i++){int x,y,z;scanf("%d%d%d",&e[i].u,&e[i].v,&e[i].w);}
    41     for(int i=1;i<=s;i++)add(e[i].u,e[i].v,e[i].w);
    42     defense(e+1,s);
    43     spfa(t);
    44     for(int i=1;i<=n;i++) printf("%d ",d[i]==0x3f3f3f3f?2147483647:d[i]);
    45 }
    spfa(defense)
     1 #include<stdio.h>
     2 #include<string.h>
     3 const int maxN=10005,maxM=500005;
     4 int top=0,head[maxN],to[maxM],nxt[maxM],val[maxM];
     5 void add(int u,int v,int w){top++;to[top]=v,nxt[top]=head[u],val[top]=w;head[u]=top;}
     6 struct queue{
     7     int head,tail,data[maxM];
     8     queue(){head=1,tail=0;}
     9     void push(int x){data[tail=(tail+1)%maxM]=x;}
    10     void pop(){head=(head+1)%maxM;}
    11     int front(){return data[head];}
    12     bool empty(){return tail<head;}
    13 }q;
    14 int d[maxN];
    15 void spfa(int u){
    16     memset(d,0x3f,sizeof(d));
    17     d[u]=0; q.push(u);
    18     while(!q.empty()){
    19         int tmp=q.front(),now=head[tmp]; q.pop();
    20         while(now!=0){
    21             if(d[to[now]]>d[tmp]+val[now]){
    22                 d[to[now]]=d[tmp]+val[now];
    23                 q.push(to[now]);
    24             }
    25             now=nxt[now];
    26         }
    27     }
    28 }
    29 int main(){
    30 //    freopen("1.in","r",stdin);
    31     int n,s,t; scanf("%d%d%d",&n,&s,&t);
    32     for(int i=1;i<=s;i++){
    33        int x,y,z;scanf("%d%d%d",&x,&y,&z);add(x,y,z);    
    34     }
    35     spfa(t);
    36     for(int i=1;i<=n;i++) printf("%d ",d[i]==0x3f3f3f3f?2147483647:d[i]);
    37 }
    spfa
     1 #include<cstdio>
     2 #include<queue>
     3 #define MAXN 1000005
     4 #define inf 0x7fffffff
     5 #define debug 0
     6 using namespace std;
     7 #if debug
     8     int cnt_dij=0;
     9 #endif
    10 typedef pair<int,int> pa;
    11 int n,m,s;
    12 struct edge{
    13     int to,nxt,val;
    14 }e[MAXN];
    15 int head[MAXN],cnt=0;
    16 inline void add(int u,int v,int w){
    17     cnt++,e[cnt].to=v,e[cnt].nxt=head[u],head[u]=cnt;e[cnt].val=w;
    18 }
    19 int d[MAXN];
    20 inline void dij(){
    21     priority_queue<pa,vector<pa>,greater<pa> >q;
    22     fill(d,d+n+1,inf);d[s]=0;q.push(pa(s,0));  
    23     while(!q.empty()){
    24         pa p=q.top();q.pop();
    25         int val=p.second;
    26         //if(d[val]<p.first) continue;
    27         for(int i=head[p.first];i;i=e[i].nxt){
    28             int to=e[i].to;
    29             if(d[to]>val+e[i].val) d[to]=val+e[i].val,q.push(pa(to,d[to]));
    30         }
    31     }
    32 }
    33 int main(){
    34     scanf("%d%d%d",&n,&m,&s);
    35     for(int i=1;i<=m;i++) {
    36         int x,y,z;scanf("%d%d%d",&x,&y,&z);add(x,y,z);
    37     }
    38     dij();
    39     for(int i=1;i<=n;i++) printf("%d ",d[i]);
    40     return 0;
    41 }
    dijstra
     1 //bellman_ford 
     2 for(int i=0;i<n;i++) d[i]=INF;
     3 d[0]=0;
     4 for(int k=0;k<n-1;k++){//迭代n-1次 
     5     for(int i=0;i<m;i++)//检查每条边 
     6     {
     7       int x=u[i],y=v[i];
     8       if(d[x]<INF) d[y]=min(d[y],d[x]+w[i]);//松驰 
     9     } 
    10 } 
    11 //SPFA 
    12 Bool bellman_ford(int s){
    13     queue<int> Q; 
    14     memset(inq,0,sizeof(inq));//inq[i]用于标记i点是否在队列中 
    15     memset(cnt,0,sizeof(cnt));//cnt[i]用于记录i点进队次数 
    16     for(int i=0;i<n;i++)d[i]=INF;//初始化d数组 
    17     d[s]=0;inq[s]=true;//源点到自己最短路长为0,s点进队 
    18     Q.push(s);
    19     
    20     while(!Q.empty()){            //当队列非空时 
    21         int u=Q.front();Q.pop();//取队头元素给u 
    22         inq[u]=false;            //u点不在队 
    23         for(int i=0;i<G[u].size();i++){//扫描u点出发所有边 
    24             Edge &e=edges[G[u][i]];
    25             if(d[u]<INF && d[e.to]>d[u]+e.dist){//如果可以通过u松驰 
    26                 d[e.to]=d[u]+e.dist;//松驰 
    27                 if(!inq[e.to]){        //如果e.to不在队中,将它入队 
    28                     Q.push(e.to);inq[e.to]=true;
    29                     //如果e.to入队次数>n,则存在负环,返回false 
    30                     if(++cnt[e.to])>n) return false; 
    31                 }
    32             }
    33         }
    34     }
    35     return true; 
    36 } 
    37 
    38 //floyd 
    39 int d[Max_v][Max_v];
    40 //d[u][v]表示边e=(u,v)的权值(不存在时设为INF,不过d[i][i]=0 
    41 int V;    //顶点数 
    42 
    43 void warshall_floyd(){
    44     for (int k=0;k<V;k++){
    45         for(int i=0;i<V;i++)
    46           for(int j=0;j<V;j++)
    47             d[i][j]=min(d[i][j],d[i][k]+d[k][j]);
    48     } 
    49 }
    SPFA&floyd

    最小生成树

     1 #include<stdio.h>
     2 #include<algorithm> 
     3 using namespace std;
     4 const int Max_E=10000;
     5 struct edge{int u;int v;int cost;};        //边结构 
     6 bool comp(const edge& e1,const edge& e2){
     7     return e1.cost<e2.cost;
     8 }
     9 edge es[Max_E];    //边集 
    10 int fa[Max_E];     //并查集 
    11 int V,E;        //顶点数与边数 
    12 void init_union_find(int n){//初始化并查庥 
    13     for(int i=0;i<n;i++) fa[i]=i;
    14 }
    15 int find(int x){//并查集中查找操作 
    16     if(fa[x]==x) return x;
    17     return fa[x]=find(fa[x]);    
    18 } 
    19 void unite(int x,int y){//并操作 
    20     int fx=find(x),fy=find(y);
    21     if(fx==fy) return ;
    22     fa[fx]=fy;
    23 }
    24 int kruskal(){
    25     sort(es,es+E,comp);    //按edge.cost的顺序从小到大排序 
    26     init_union_find(V);    //初始化并查集,每个点就是一个并查集 
    27     int res=0;
    28     for(int i=0;i<E;i++){//扫描每一条边 
    29       edge e=es[i];    
    30       if(find(e.u)!=find(e.v)){//如果e边的起点与终点不在同一个集合 
    31             unite(e.u,e.v);        //将这条边加入生成树,将它们所在集合合并 
    32             res+=e.cost;
    33       }
    34     }
    35     return res; 
    36 }
    37 int main(){
    38     int u,v,cost;
    39     scanf("%d%d",&V,&E);
    40     for(int i=0;i<E;i++){
    41         scanf("%d%d%d",&u,&v,&cost);
    42         es[i]=edge{u,v,cost};
    43     }
    44     printf("%d
    ",kruskal());
    45     return 0;
    46 }
    kruskal
     1 #include<iostream>
     2 using namespace std;
     3 const int Max_v=1000;        //最大顶点数 
     4 const int INF=0x7fffffff;     
     5 int cost[Max_v][Max_v];        //邻接矩阵 
     6 int mincost[Max_v];            //从集合X出发的边到每个顶点的最小权值。 
     7 bool used[Max_v];            //顶点i是否包含在集合Xk  
     8 int V;                        //顶点数 
     9 int prim(){
    10     fill(mincost,mincost+V,INF);         
    11     fill(used,used+V,false);
    12     mincost[0]=0;
    13     int res=0;
    14     while(true){
    15         int v=-1;
    16         //从不属于X的顶点中选取从X到其权值最小的顶点
    17         for(int u=0;u<V;u++){
    18             if(!used[u]&&(v==-1||mincost[u]<mincost[v])) v=u;
    19         }
    20         if(v==-1) break;
    21         used[v]=true;
    22         res+=mincost[v];
    23         for(int u=0;u<V;u++) 
    24         if (cost[v][u])mincost[u]=min(mincost[u],cost[v][u]); 
    25     }
    26     return res;
    27 }
    28 int main(){
    29     cin>>V;
    30     for(int i=0;i<V;i++)
    31       for(int j=0;j<V;j++)
    32       cin>>cost[i][j];
    33     cout<<prim();
    34     return 0;
    35 }
    prim
     1 //最小生成树Prim算法 用上了堆(优先队列)优化  vijos 1190
     2 #include<iostream>
     3 #include<queue>
     4 #include<cstdio>
     5 #include<cstring>
     6 using namespace std;
     7 const int Max_v=1001;
     8 struct node{        //优先队列(最小堆)结构 
     9     int no,cost;    //顶点编号、顶点到生成树的权 
    10     bool operator <(const node &a)const{
    11       return cost > a.cost;
    12     }
    13 };
    14 struct data{int to,w;};        //邻接表结点结构 
    15 vector<data> G[Max_v];        //邻接表头结点 
    16 int n,m,ans,mincost[Max_v];    //n,m分别表示顶点数与边数,mincost[i]为目前生成树到i的权 
    17 bool mark[Max_v];            //标志数组,mark[i]标志i是否已经加入生成树 
    18 priority_queue<node> q;        //优先队列q是一个最小堆,存储每个点编号及最小权 
    19 void Ins(int u,int v,int w){//往图中插入一条边(u,v,w) 
    20     data e;    e.to=v;e.w=w;G[u].push_back(e);
    21 }
    22 void init(){                //输入n与m及m条边,初始化建图 
    23     int i,a,b,c;
    24     scanf("%d%d",&n,&m);
    25     for(i=1;i<=m;i++){
    26         scanf("%d%d%d",&a,&b,&c);
    27         Ins(a,b,c);Ins(b,a,c);
    28     }
    29 }
    30 void prim_queue(){
    31     int num=0,now;
    32     memset(mincost,127,sizeof(mincost));
    33     mincost[1]=0;//从1号点开始,将1号点加入生成树T,1号点到t的最小权为0 
    34     node P={1,0};q.push(P);//将(1,0)加入优先队列 
    35     while(!q.empty()){        //当队列非空 
    36         P=q.top();q.pop();    //取优先队列中cost值最小的点now
    37         now=P.no;            
    38         if(mark[now]) continue;//如果now已经在生成树中,继续循环 
    39         mark[now]=1;            //将now点加入生成树T 
    40         ans+=mincost[now];        //答案加now到树的权 
    41         for(int i=0;i<G[now].size();i++){//更新与now相邻那些点的mincost 
    42             data e=G[now][i];
    43             if(e.w<mincost[e.to]){        //如果(now,e.to)的权w小球mincost[e.to] 
    44                 mincost[e.to]=e.w;        //修改mincost[e.to],并将(e.to,e.w)入优先队列 
    45                 P.no=e.to;P.cost=e.w;
    46                 q.push(P);
    47             }
    48         }
    49     }
    50     printf("%d
    ",ans);
    51 }
    52 int main(){
    53     init();
    54     prim_queue();
    55     return 0;
    56 }
    prim(queue)
  • 相关阅读:
    什么是C/S和B/S结构(二)转
    程序员的爱情独白(转)
    为什么美女喜欢软件开发的gg做老公
    C# DataGridView中 显示行号
    联想F31笔记本配置分析
    理解.NET中的数据库连接池[转]
    C#获取当前路径的方法集合
    vb6,vs2005快捷键使用,提高操作速度[转]
    Visual Studio Team System 2008 Team Suite (VSTS 2008) 简体中文正式版下载(正在下载中 60K/秒)
    一个正在项目中使用的DataInterface数据访问接口
  • 原文地址:https://www.cnblogs.com/drizzly/p/7689012.html
Copyright © 2011-2022 走看看