最短路系列:
spfa:
#define Min(a,b) (a<b?a:b) #define Max(a,b) (a>b?a:b) #define Abs(a) ((a)>0?(a):-(a)) #define Mod(a,b) (((a)-1+(b))%(b)+1)
int n,m; int d[N]; struct { int v,w,next; }edge[2*M]; int edgehead[N]; int k; bool vis[N]; void addedge(int u,int v,int w) { edge[k].next=edgehead[u]; edge[k].w=w; edge[k].v=v; edgehead[u]=k++; } int spfa(int s) { queue<int> que; for(int i=1;i<=n;i++) d[i]=inf; d[s]=0; memset(vis,0,sizeof(vis)); que.push(s); while(!que.empty()) { int u=que.front(); que.pop(); vis[u]=false; for(int i=edgehead[u];i;i=edge[i].next) { int v=edge[i].v; int w=edge[i].w; if(d[v]>d[u]+w) { d[v]=d[u]+w; if(!vis[v]) { que.push(v); vis[v]=true; } } } } return d[n]; } int main() { scanf("%d%d",&m,&n); int u,v,w; k=1; for(int i=1;i<=m;i++) { scanf("%d%d%d",&u,&v,&w); addedge(u,v,w); addedge(v,u,w); } printf("%d\n",spfa(1)); return 0; }
int n,m; int d[N]; struct { int v,w,next; }edge[2*M]; int edgehead[N]; int k; bool vis[N]; void addedge(int u,int v,int w) { edge[k].next=edgehead[u]; edge[k].w=w; edge[k].v=v; edgehead[u]=k++; } struct cmp { bool operator ()(const int a,const int b) { return d[a]>d[b]; } }; int dijstra(int s) { priority_queue<int,vector<int>,cmp> que; for(int i=1;i<=n;i++) d[i]=inf; d[s]=0; memset(vis,0,sizeof(vis)); que.push(1); while(!que.empty()) { int u=que.top(); que.pop(); if(vis[u]) continue; vis[u]=true; for(int i=edgehead[u];i;i=edge[i].next) { int v=edge[i].v; int w=edge[i].w; if(!vis[v]&&d[v]>d[u]+w) { d[v]=d[u]+w; que.push(v); } } } return d[n]; } int main() { scanf("%d%d",&m,&n); int u,v,w; k=1; for(int i=1;i<=m;i++) { scanf("%d%d%d",&u,&v,&w); addedge(u,v,w); addedge(v,u,w); } printf("%d\n",dijstra(1)); return 0; }
dinic:
int n,m; int mat[N][N]; bool vis[N]; int level[N]; bool bfs(int s,int t) { memset(vis,0,sizeof(vis)); memset(level,0,sizeof(level)); queue<int> que; que.push(s); vis[s]=true; level[s]=0; while(!que.empty()) { int now=que.front(); que.pop(); if(now==t) { return true; } for(int i=0;i<n;i++) { if(!vis[i]&&mat[now][i]) { vis[i]=true; level[i]=level[now]+1; que.push(i); } } } return false; } int dinic(int now,int sum,int t) { if(now==t) return sum; int os=sum; for(int i=0;i<n && sum;i++) { if(mat[now][i] && level[i]==level[now]+1) { int ret=dinic(i,Min(sum,mat[now][i]),t); mat[now][i]-=ret; mat[i][now]+=ret; sum-=ret; } } return os-sum; } void solve(int s,int t)//s是源点,t是汇点。 { int ans=0; while(bfs(s,t)) ans+=dinic(s,inf,t); printf("%d\n",ans); }
二分图最大匹之配匈牙利算法:
int n,m; bool mat[N][N]; bool vis[N]; int link[N]; bool dfs(int now) { for(int i=1;i<=m;i++) { if(mat[now][i]&&!vis[i]) { vis[i]=true; if(link[i]==0||dfs(link[i])) { link[i]=now; return true; } } } return false; } int main() { while(scanf("%d%d",&n,&m)!=EOF) { memset(link,0,sizeof(link)); memset(mat,0,sizeof(mat)); for(int i=1;i<=n;i++) { int tmp,v; scanf("%d",&tmp); for(int j=1;j<=tmp;j++) { scanf("%d",&v); mat[i][v]=true; } } int ans=0; for(int i=1;i<=n;i++) { memset(vis,0,sizeof(vis)); if(dfs(i)) ans++; } printf("%d\n",ans); } return 0; }
最小生成树系列:
prim:
int n,m; int mat[N][N]; int key[N],pre[N]; bool vis[N]; void prim() { memset(vis,0,sizeof(vis)); int k; for(int i=1;i<=n;i++) key[i]=mat[1][i],pre[i]=1; vis[1]=true; for(int i=1;i<n;i++) { int min=inf; for(int j=1;j<=n;j++) { if(!vis[j] && min>key[j]) { min=key[j]; k=j; } } vis[k]=true; if(mat[k][pre[k]]!=0) { printf("%d %d\n",k,pre[k]); } for(int j=1;j<=n;j++) { if(!vis[j]&&key[j]>mat[k][j]) pre[j]=k,key[j]=mat[k][j]; } } }
int n,m; const int N=1005,M=15005; const int inf=99999999; int father[N]; struct Edge { int u,v,w; }edge[M],output[M]; int findfa(int now) { while(father[now]>0) { now=father[now]; } return now; } void Union(int a,int b) { if(father[a]>father[b]) { father[a]+=father[b]; father[b]=a; } else { father[b]+=father[a]; father[a]=b; } } bool cmp(const Edge & a,const Edge & b) { return a.w<b.w; } void kruskal() { memset(father,-1,sizeof(father)); sort(edge,edge+m,cmp); int count=n-1,k=0,u,v,w,fu,fv; for(int i=0;i<m;i++) { u=edge[i].u; v=edge[i].v; w=edge[i].w; fu=findfa(u); fv=findfa(v); if(fu!=fv) { output[k]=edge[i]; Union(fu,fv); k++; } } printf("%d\n%d\n",output[n-2].w,n-1); for(int i=0;i<n-1;i++) printf("%d %d\n",output[i].u,output[i].v); }