模板 图论

存图

 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)
原文地址:https://www.cnblogs.com/drizzly/p/7689012.html