一:最短路
1:Floyd
void Floyd() { for(int k=1;k<=n;k++) { for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) { dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]); } } } }
extend:Floyd求最小环
for(int i=1;i<=top;i++){ for(int j=1;j<=top;j++){ dis[i][j]=w[i][j]=INF; } } for(int i=1;i<=top;i++){ for(int j=i;j<=top;j++){ if(a[i]&a[j])dis[i][j]=dis[j][i]=w[i][j]=w[j][i]=1; if(i==j)dis[i][j]=w[i][j]=0; } } ll minn=INF; for(int k=1;k<=top;k++){ for(int i=1;i<k;i++){ for(int j=i+1;j<k;j++){ minn=min(minn,dis[i][j]+w[i][k]+w[k][j]); } } for(int i=1;i<=top;i++){ for(int j=1;j<=top;j++){ dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]); } } } if(minn==INF)cout<<"-1"<<endl; else cout<<minn<<endl;
2:Dijkstra
void Dijkstra(int s) { memset(dis,INF,sizeof(dis)); memset(vis,0,sizeof(vis)); for(int i=1;i<=n;i++) dis[i]=a[s][i]; vis[s]=1; for(int i=1;i<=n-1;i++) { int minn=INF,u=-1; for(int j=1;j<=n;j++) { if(dis[j]<minn&&!vis[j]) { minn=dis[j]; u=j; } } if(u==-1) //优化 break; vis[u]=1; for(int v=1;v<=n;v++) { if(!vis[v]&&dis[v]>dis[u]+a[u][v]) { dis[v]=dis[u]+a[u][v]; } } } }
void Dijkstra(int s) { priority_queue<P,vector<P>,greater<P> >que; que.push(P(0,s)); dis[s]=0; while(!que.empty()) { P p=que.top(); que.pop(); int u=p.second; if(vis[u]) continue; vis[u]=1; for(int i=head[u]; i!=-1; i=e[i].next) { int v=e[i].v; int w=e[i].w; if(!vis[v]&&dis[v]>dis[u]+w) { dis[v]=dis[u]+w; que.push(P(dis[v],v)); } } } }
3:SPFA
void SPFA(int s) { dis[s]=0; queue<int>que; que.push(s); while(!que.empty()) { int u=que.front(); que.pop(); vis[u]=0; //出队 for(int i=head[u];i!=-1;i=e[i].next) { int v=e[i].v; int w=e[i].w; if(dis[v]>dis[u]+w) { dis[v]=dis[u]+w; if(vis[v]) continue; vis[v]=1; que.push(v); } } } }
4:最大流
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int INF=0x3f3f3f3f; const int maxn = 200010; const int mod=1000000007; int a[maxn],b[maxn],level[maxn],cnt,head[maxn]; int n,m; struct node { int v,w,next; }e[maxn*2]; void add(int u,int v,int w) { e[cnt].v=v; e[cnt].w=w; e[cnt].next=head[u]; head[u]=cnt++; } int BFS() { memset(level,-1,sizeof(level)); queue<int>que; que.push(1); level[1]=0; while(!que.empty()){ int u=que.front(); que.pop(); for(int i=head[u];i!=-1;i=e[i].next){ int v=e[i].v; int w=e[i].w; if(level[v]==-1&&w>0){ level[v]=level[u]+1; if(v==n)return 1; que.push(v); } } } return 0; } int DFS(int u,int flow) { if(u==n)return flow; int Flow=0; for(int i=head[u];i!=-1;i=e[i].next){ int v=e[i].v; int w=e[i].w; if(level[v]==level[u]+1&&w>0){ int d=DFS(v,min(flow,w)); if(d>0){ flow-=d; Flow+=d; e[i].w-=d; e[i^1].w+=d; if(flow==0)break; } } } return Flow; } int main() { while(cin>>m>>n){ memset(head,-1,sizeof(head)); cnt=0; for(int i=1;i<=m;i++){ int u,v,w; cin>>u>>v>>w; add(u,v,w); add(v,u,0); } int ans=0; while(BFS()){ ans+=DFS(1,INF); } cout<<ans<<endl; } return 0; }
5:最大流优化
#include<iostream> #include<string> #include<cstring> #include<vector> #include<queue> using namespace std; typedef long long ll; const int INF=0x3f3f3f3f; const int maxn=100010; struct edge { int v,cap,rev; }; int level[maxn],iter[maxn]; vector<edge>G[maxn]; void add(int u,int v,int cap) { G[u].push_back((edge){v,cap,(int)G[v].size()}); G[v].push_back((edge){u,0,(int)G[u].size()-1}); } void bfs(int s) { memset(level,-1,sizeof(level)); queue<int>que; level[s]=0; que.push(s); while(!que.empty()){ int u=que.front(); que.pop(); for(int i=0;i<G[u].size();i++){ edge &e=G[u][i]; int v=e.v; if(e.cap>0&&level[v]<0){ level[v]=level[u]+1; que.push(v); } } } } int dfs(int u,int t,int f) { if(u==t)return f; for(int &i=iter[u];i<G[u].size();i++){ edge &e=G[u][i]; int v=e.v; if(e.cap>0&&level[v]>level[u]){ int d=dfs(v,t,min(f,e.cap)); if(d>0){ e.cap-=d; G[v][e.rev].cap+=d; return d; } } } return 0; } int Dinic(int s,int t) { int flow=0; for(;;){ bfs(s); if(level[t]<0)return flow; memset(iter,0,sizeof(iter)); int f; while((f=dfs(s,t,INF))>0){ flow+=f; } } return flow; } int main() { int m,n; while(cin>>m>>n){ for(int i=1;i<=n;i++)G[i].clear(); for(int i=1;i<=m;i++){ int u,v,w; cin>>u>>v>>w; add(u,v,w); } int ans=Dinic(1,n); cout<<ans<<endl; } return 0; }
强连通分量:
#include<bits/stdc++.h> #define ll long long using namespace std; const int maxn = 1e6 + 5; const int inf = 0x3f3f3f3f; int dfn[maxn],low[maxn],head[maxn],belong[maxn]; //dfs序编号,最早能访问到的祖先编号,belong[i]代表i属于哪一个强连通分量 int num[maxn];//num[i]代表i这个强连通分量中有多少个元素 stack<int>sta; int dfs_clock,cnt,scc_cnt;//DFS中的编号,边的编号,强连通分量的编号 struct node { int v,next; }e[maxn]; void add(int u,int v) { e[cnt]=(node){v,head[u]}; head[u]=cnt++; } void DFS(int u) { sta.push(u); low[u]=dfn[u]=++dfs_clock; for(int i=head[u];i!=-1;i=e[i].next){ int v=e[i].v; if(!low[v]){ DFS(v); low[u]=min(low[u],low[v]); } else if(!belong[v]) low[u]=min(low[u],dfn[v]); } if(low[u]==dfn[u]){//以u为起点的搜索子树是一个强连通分量 scc_cnt++; for(;;){ int now=sta.top(); sta.pop(); belong[now]=scc_cnt; if(now==u)break; } } } int main(){ int n,m; cin >> n >> m; for(int i = 0;i <= n;i++)head[i]=-1; for(int i = 1;i <= m;i++){ int u,v; cin >> u >> v; add(u,v); } for(int i = 1;i <= n;i++){ if(!dfn[i])DFS(i); } for(int i = 1;i <= n;i++){ num[belong[i]]++;//i属于的强连通分量元素个数+1 } int mx=0;//强连通分量中包含的最大的元素个数 for(int i = 1;i <= scc_cnt;i++){ mx=max(mx,num[i]); } cout<<mx<<endl; return 0; }