【算法模板】图论

dji:

#include <iostream>
#include <cstring>
#include <vector>
#include <queue>
#define N 100 
using namespace std;
typedef struct No
{
	int u,v,w;
	No(int a,int b,int c){u=a,v=b,w=c;}
	bool operator<(const No &dd)const{
        return w>dd.w;
    }
}No;
int dist[N];
vector<No> q[N];

void Dji(int n0)
{
	int vis[N];
	memset(vis,0,sizeof(vis));
	memset(dist,63,sizeof(dist));
	dist[n0]=0;
	vis[n0]=1;
	priority_queue<No>que;
	que.push(No(0,n0,dist[n0]));
	while (!que.empty())
	{
		No x=que.top();que.pop();
		for (int i=0;i<q[x.v].size();i++)
		{
			No y=q[x.v][i];
			if (dist[y.v]>dist[x.v]+y.w)
			{
				dist[y.v]=dist[x.v]+y.w;
				que.push(No(x.v,y.v,dist[y.v]));
			}
		}
	}
}
int main()
{
	int m,n;
	cin>>n>>m;
	for (int i=0;i<m;i++)
	{
		int u,v,w;
		cin>>u>>v>>w;
		q[u].push_back(No(u,v,w));
		q[v].push_back(No(v,u,w));
	}
	int uu;
	cin>>uu;
	Dji(uu);
	for (int i=1;i<=n;i++)
	 if (i!=uu) cout<<uu<<" to "<<i<<" mincost:"<<dist[i]<<endl;
	 cout<<endl;
}


/*
7 11
1 2 7
1 4 5
2 4 9
2 3 8
2 5 7
4 5 15
4 6 6
6 5 8
6 7 11
5 7 9
3 5 5


*/


floyd:

#include<cstdio>
#include<iostream>
#define maxx 101
using namespace std;
int map[maxx][maxx],n,i,j,k,a,b,q;
int main()
{
    scanf("%d\n",&n);
    for (i=1;i<=n;i++)
      for (j=1;j<=n;j++)
       {
	   scanf("%d",&map[i][j]);
       if (map[i][j]==-1) map[i][j]=100000;
   }
    for (k=1;k<=n;k++)
     for (i=1;i<=n;i++) if (i!=k)
      for (j=1;j<=n;j++)  if (i!=j&&j!=k)
      	{
           if  ((map[i][k]+map[k][j]<map[i][j]))map[i][j]=map[i][k]+map[k][j];           
		}
	cout<<"查询组数:";
	cin>>q;
    for (i=1;i<=q;i++) 
    {
      cin>>a>>b;
     cout<<"min:"<<map[a][b]<<endl;
    }
    return 0;
}
/*
7
0 7 -1 5 -1 -1 -1
7 0 8 9 7 -1 -1
-1 8 0 -1 5 -1 -1 
5 9 -1 0 15 6 -1
-1 7 5 15 0 8 9
-1 -1 -1 6 8 0 11
-1 -1 -1 -1 9 11 0
6
1 2 
1 3
1 4
1 5
1 6
1 7

*/


kruskal:

#include<cstdio>
#include<iostream>
#include<cstdlib>
#define maxx 100000
using namespace std;
typedef struct edge{int x,y,w;}edge;
edge e[maxx];
int r[maxx],f[maxx];
long long sum=0;
int find(int x)
{
	return x==f[x]?x:f[x]=find(f[x]);
}

int cmp(const void *a, const void *b)
{
	if ((*(edge *)a).w == (*(edge *)b).w)
	 return (*(edge *)a).w-(*(edge *)b).w;
	return (*(edge *)a).w-(*(edge *)b).w ; 
}
int main()
{   
	ios::sync_with_stdio(false);
   	int i,n,m,x,y,chx,chy;
    cin>>m>>n;
    for (i=0;i<n;i++)
    {
    	cin>>e[i].x>>e[i].y>>e[i].w;
    	f[i]=i;
    	r[i]=0;
    }
	qsort(e,n,sizeof(edge),cmp);
	sum=0;
	for (i=0;i<n;i++)
	 {
	 	x=find(e[i].x); y=find(e[i].y);
	 	if (x!=y)  
		{
	 		if (r[x]>r[y]) f[y]=x;
	 		else
	 		{
	 			if (r[x]==r[y]) r[y]++;
	 			f[x]=y;
	 		}
	 		sum+=e[i].w;
	 		cout<<e[i].x<<"<=>"<<e[i].y<<"  cost:"<<e[i].w<<endl; 
		}
	 }
	 cout<<"mincost:"<<sum<<endl;
	 return 0;
}
/*

7 11
1 2 7
1 4 5
2 4 9
2 3 8
2 5 7
4 5 15
4 6 6
6 5 8
6 7 11
5 7 9
3 5 5

*/


prim:

#include<cstdio>
#include<iostream>
using namespace std;
#define M 101
int map[M][M]={0},cost[M]={0},vis[M]={0},i,j,n,min1,ans=0;
int main()
{
    scanf("%d",&n);
    for (i=1;i<=n;i++)   for (j=1;j<=n;j++)  scanf("%d",&map[i][j]);
    ans=0;
    for (i=1;i<=n;i++)
     {
     	cost[i]=map[i][1];
     	vis[i]=1;
     }
     vis[1]=-1;
    for (i=1;i<=n;i++)
     {
      min1=1000000;
	  int v=-1;
	  for (j=1;j<=n;j++)
	   if (vis[j]!=-1&&cost[j]<min1)
	   {
	   	v=j;
	    min1=cost[j];
	   } 
	   if (v!=-1)
	   {
	   	cout<<i<<"<=>"<<v<<" cost"<<min1<<endl;
	   	ans+=min1;
		   vis[v]=-1;
	   	
	   	for (j=1;j<=n;j++) if (vis[j]!=-1&&map[v][j]<cost[j])
	   	{
	   		cost[j]=map[v][j];
	   		vis[j]=v;
	   	}
	   }
     }
    printf("mincost:%d",ans);
    return 0;
}
/*
4

0  4  9 21

4  0  8 17

9  8  0 16

21 17 16  0


*/
 


spfa:

void Spfa()  
{  
    memset(Dis,63,sizeof(Dis));  
    Dis[1]=0;  
    Vis[1]=true;  
    deque<int> Q;  
    Q.push_back(1);  
    while(!Q.empty())  
    {  
        int u=Q.front();  
        for(Node *i=G[u].nxt;i;i=i->nxt)  
        {  
            int v=i->to,w=i->w;  
            if(Dis[v]>Dis[u]+w)  
            {  
                Dis[v]=Dis[u]+w;  
                if(Vis[v])continue;  
                Vis[v]=true;  
                if(!Q.empty())  
                {  
                    if(Q.front()>Dis[v])Q.push_front(v);  
                    else Q.push_back(v);  
                }  
                else Q.push_back(v);  
            }  
        }  
        Vis[u]=false;  
    }  
}  


topo-DAG:

#include <iostream>
#include <cstring>
#include <vector>
#include <queue>
#define N 100 
#define maxx 9999999
#define minn -1
using namespace std;
typedef struct No 
{
	int u,v,w;
	No(int a,int b,int c){u=a,v=b,w=c;}
}No;
vector<No> T[N];
vector<int> topol;
int dist[N];
bool vis[N];

void topo(int now)
{
	if (!vis[now]) vis[now]=1;
	for (int i=0;i<T[now].size();i++)
	{
		if (!vis[T[now][i].v]) topo(T[now][i].v);
	}
	topol.push_back(now);
}
void DAG(int n,int k)
{
	for (int i=1;i<=n;i++) dist[i]=maxx;
	dist[k]=0;
	for (int i=1;i<=n;i++)
	{
		for (int j=0;j<T[i].size();j++)
		{
			int to=T[i][j].v;
			if (dist[to]>dist[i]+T[i][j].w)	dist[to]=dist[i]+T[i][j].w;
		}
	}
	return; 
}
int main()
{
	int m,n;
	cin>>n>>m;
	for (int i=0;i<m;i++)
	{
		int u,v,w;
		cin>>u>>v>>w;
		T[u].push_back(No(u,v,w));
	}
	memset(vis,0,sizeof(vis));
	for (int i=1;i<=n;i++) if(!vis[i]) topo(i);
	for (int i=topol.size()-1;i>=0;i--) cout<<topol[i]<<" ";
	cout<<endl;
	int k;
	cin>>k;
	DAG(n,k);
	for (int i=1;i<=n;i++)	cout<<k<<" to "<<i<<" mincost:"<<dist[i]<<endl;
	cout<<endl;
}


/*
7 11
1 2 7
1 4 5
2 4 9
2 3 8
2 5 7
4 5 -5
4 6 6
5 6 8
6 7 11
5 7 9
3 5 5


*/


无向图双联通分支,割点:

#include<iostream>
#include<cstring>
#include<vector>
#include<stack>
#define N 1000
using namespace std;
typedef struct dd
{
	int u;int v;
}dd;
int flag[N],low[N],df[N],dfsnum=0,num=0;
vector<int> gra[N];
vector<int> gp;
vector<dd> bri;
stack<int> s;
void tarjan(int u,int fa)
{
    flag[u]=low[u]=++dfsnum;
    s.push(u);
    int ch=0;
    for(int i=0;i<gra[u].size();i++)
    {
        int v=gra[u][i];
        if(!flag[v])
        {
        	ch++;
			df[v]=u;
            tarjan(v,u);
            low[u]=min(low[u],low[v]);
            if (df[u]==-1 && ch>1) 	gp.push_back(u);
            if (df[u]!=-1 && flag[u]<=low[v])	
			{ 
				gp.push_back(u);
			} 
		}
        else if(v!=fa)
        {
            low[u]=min(low[u],flag[v]);
        }
    }
    if(low[u]==flag[u])
    {
        num++;
        cout<<"NO."<<num<<" : ";
        while (1)
        {
            int x=s.top();
            cout<<x<<" ";
            s.pop();
            if(x==u)
            {
            	cout<<endl;
                break;
        	}
		}
    }
}
int main()
{
	int m,n;
	cin>>n>>m;
	memset(df,-1,sizeof(df));
	memset(flag,0,sizeof(flag));
	for (int i=0;i<m;i++)
	{
		int u,v;
		cin>>u>>v;
		gra[u].push_back(v);
		gra[v].push_back(u);
	//	df[u]=v;df[v]=u;
		dd sd;
		sd.u=u;
		sd.v=v;
		bri.push_back(sd);
	}
	cout<<"对于边的双连通分支:"<<endl; 
	for (int i=0;i<n;i++)
	if (!flag[i]) tarjan(i,-1);
	cout<<"割点:"<<endl; 
	for (int i=0;i<gp.size();i++) cout<<gp[i]<<" ";
	cout<<endl<<"桥:"<<endl; 
	for (int i=0;i<m;i++)
	{
		int uu=bri[i].u,vv=bri[i].v;
		if (flag[uu]<low[vv]) cout<<uu<<"<->"<<vv<<endl;
	}
	//for(int i=0;i<n;i++)cout<<low[i]<<" "<<flag[i]<<" "<<df[i]<<endl;
	return 0;
}

有向图强连通分支:

#include<iostream>
#include<cstring>
#include<vector>
#include<stack>
#define N 1000
using namespace std;
typedef struct dd
{
	int u;int v;
}dd;
int flag[N],low[N],df[N],dfsnum=0,num=0;
vector<int> gra[N];
vector<int> gd;
stack<int> s;;
void tarjan(int u)
{
    flag[u]=low[u]=++dfsnum;
    s.push(u);
    df[u]=1; 
    for(int i=0;i<gra[u].size();i++)
    {
        int v=gra[u][i];
        if(!flag[v])
        {
            tarjan(v);
            low[u]=min(low[u],low[v]);
        }
        else if(df[v])
        {
            low[u]=min(low[u],flag[v]);
        }
    }
    if(low[u]==flag[u])
    {
    	gd.push_back(u);
        num++;
        cout<<"NO."<<num<<" : ";
        while (1)
        {
            int x=s.top();
            cout<<x<<" ";
            s.pop();
            df[x]=0;
            if(x==u)
            {
            	cout<<endl;
                break;
        	}
		}
    }
}
int main()
{
	int m,n;
	cin>>n>>m;
	for (int i=0;i<m;i++)
	{
		int u,v;
		cin>>u>>v;
		gra[u].push_back(v);
	}
	cout<<"强连通分支:"<<endl; 
	memset(flag,0,sizeof(flag));
	memset(df,0,sizeof(df));
	for (int i=0;i<n;i++)
	if (!flag[i]) tarjan(i);
	for (int i=0;i<gd.size();i++) cout<<gd[i]<<" ";
	return 0;
}

/*

6 8
0 2
0 1
3 0
1 3
4 5
3 5
2 4
2 3





*/


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值