大神们都整理完了…我现在才来整理QAQ
最短路のSPFA:
可以判负环并且支持乱搞!
发一波最短路+判负环+记录路径(倒着输出)
#include
#include
#include
#include
#include
using namespace std;
const int MAX_V=2500+10;
const int MAX_E=5200+10;
int first[MAX_V],nxt[MAX_E<<1],d[MAX_V];
struct edge{
int from,to,cost;
}es[MAX_E<<1];
int tot;
int V,E,Ts,Te;
void build(int ff,int tt,int dd)
{
es[++tot]=(edge){ff,tt,dd};
nxt[tot]=first[ff];
first[ff]=tot;
}
bool vis[MAX_V];
int tim[MAX_V];
int prev[MAX_V];
queue<int>q;
bool spfa(int s)
{
d[s]=0;
vis[s]=1;
q.push(s);
while(!q.empty())
{
int u=q.front();
q.pop();
vis[u]=0;
for(int i=first[u];i!=-1;i=nxt[i])
{
int v=es[i].to;
if(d[v]>d[u]+es[i].cost)
{
d[v]=d[u]+es[i].cost;
prev[v]=u;
if(!vis[v])
{
if(++tim[u]>V) return false;
vis[v]=1;
q.push(v);
}
}
}
}
return true;
}
int main()
{
memset(first,-1,sizeof(first));
memset(d,0x3f,sizeof(d));
memset(prev,-1,sizeof(prev));
scanf("%d%d%d%d",&V,&E,&Ts,&Te);
for(int i=1;i<=E;i++)
{
int ff,tt,dd;
scanf("%d%d%d",&ff,&tt,&dd);
build(ff,tt,dd);
build(tt,ff,dd);
}
if(spfa(Ts))
{
cout<for(int u=Te;u!=-1;u=prev[u]) cout<' ';
puts("");
}
else puts("-1");
return 0;
}
次短路:
#include
#include
#include
#include
#include
using namespace std;
const int SZ=200000+10;
int first[SZ],nxt[SZ<<1],d[SZ],d2[SZ];
struct edge{
int from,to,cost;
}es[SZ<<1];
int tot;
void init()
{
memset(first,-1,sizeof(first));
memset(d,0x3f,sizeof(d));
memset(d2,0x3f,sizeof(d2));
tot=0;
}
void build(int ff,int tt,int dd)
{
es[++tot]=(edge){ff,tt,dd};
nxt[tot]=first[ff];
first[ff]=tot;
}
bool vis[SZ];
queue<int>q;
void spfa(int s)
{
d[s]=0;
vis[s]=1;
q.push(s);
while(!q.empty())
{
int u=q.front();
q.pop();
vis[u]=0;
for(int i=first[u];i!=-1;i=nxt[i])
{
int v=es[i].to;
if(d[v]>d[u]+es[i].cost)
{
d2[v]=d[v];
d[v]=d[u]+es[i].cost;
if(!vis[v])
{
vis[v]=1;
q.push(v);
}
}
else if(d[v]d[u]+es[i].cost)
{
d2[v]=d[u]+es[i].cost;
if(!vis[v])
{
vis[v]=1;
q.push(v);
}
}
else if(d2[v]>d2[u]+es[i].cost)
{
d2[v]=d2[u]+es[i].cost;
if(!vis[v])
{
vis[v]=1;
q.push(v);
}
}
}
}
}
int main()
{
init();
int n,m;
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++)
{
int ff,tt,dd;
scanf("%d%d%d",&ff,&tt,&dd);
build(ff,tt,dd);
}
spfa(1);
if(d2[n]==0x3f3f3f3f)
puts("-1");
else
printf("%d\n",d2[n]);
return 0;
}
最短路のdijkstra:
发一波堆优化过的
#include
#include
#include
#include
#include
using namespace std;
const int MAX_V=2500+10;
const int MAX_E=6200+10;
int first[MAX_V],nxt[MAX_E<<1],d[MAX_V];
struct edge{
int from,to,cost;
}es[MAX_E<<1];
struct heap{
int u,v;
};
int tot;
int V,E,Ts,Te;
void build(int ff,int tt,int dd)
{
es[++tot]=(edge){ff,tt,dd};
nxt[tot]=first[ff];
first[ff]=tot;
}
bool operator < (heap a,heap b)
{
return a.v > b.v;
}
bool vis[MAX_V];
priority_queueq;
void dij(int s)
{
d[s]=0;
q.push((heap){s,0});
while(!q.empty())
{
heap x=q.top();
q.pop();
int u=x.u;
if(vis[u]) continue;
vis[u]=1;
for(int i=first[u];i!=-1;i=nxt[i])
{
int v=es[i].to;
if(d[v]>d[u]+es[i].cost)
{
d[v]=d[u]+es[i].cost;
q.push((heap){v,d[v]});
}
}
}
}
int main()
{
memset(first,-1,sizeof(first));
memset(d,0x3f,sizeof(d));
scanf("%d%d%d%d",&V,&E,&Ts,&Te);
for(int i=1;i<=E;i++)
{
int ff,tt,dd;
scanf("%d%d%d",&ff,&tt,&dd);
build(ff,tt,dd);
build(tt,ff,dd);
}
dij(Ts);
cout<return 0;
}
最小生成树のkruskal:
裸题村村通~
#include
#include
#include
#include
#include
using namespace std;
const int MAX_E=10000+10;
struct edge{
int from,to,cost;
}es[MAX_E<<1];
int fa[100+10];
int cnt=0,ans=0,V;
int find(int x)
{
if(fa[x]==x) return x;
return fa[x]=find(fa[x]);
}
bool cmp(edge a,edge b)
{
return a.costvoid kruskal()
{
for(int i=1;i<=V;i++) fa[i]=i;
sort(es+1,es+cnt+1,cmp);
for(int i=1;i<=cnt;i++)
{
int fx=find(es[i].from);
int fy=find(es[i].to);
if(fx!=fy)
{
fa[fx]=fy;
ans+=es[i].cost;
}
}
}
int main()
{
scanf("%d",&V);
for(int i=1;i<=V;i++)
for(int j=1;j<=V;j++)
{
int x;
scanf("%d",&x);
es[++cnt]=(edge){i,j,x};
}
kruskal();
cout<return 0;
}
Tarjar 找scc:
#include
#include
#include
#include
#include
using namespace std;
const int SZ=200000+10;
int first[SZ],nxt[SZ<<1];
struct edge{
int from,to,cost;
}es[SZ<<1];
int tot=0;
void build(int ff,int tt)
{
es[++tot]=(edge){ff,tt};
nxt[tot]=first[ff];
first[ff]=tot;
}
int dfn[SZ],low[SZ],scc[SZ];
int cnt=0,tim=0;
int ans=0x3f3f3f3f;
stack<int>s;
void dfs(int u)
{
low[u]=dfn[u]=++tim;
s.push(u);
for(int i=first[u];i!=-1;i=nxt[i])
{
int v=es[i].to;
if(!dfn[v])
{
dfs(v);
low[u]=min(low[u],low[v]);
}
else if(!scc[v])
low[u]=min(low[u],dfn[v]);
}
if(low[u]==dfn[u])
{
cnt++;
int cnt2=0;
while(true)
{
int x=s.top();
s.pop();
scc[x]=cnt;
cnt2++;
if(x==u)
{
if(cnt2>1) ans=min(ans,cnt2);
break;
}
}
}
}
int main()
{
memset(first,-1,sizeof(first));
int n;scanf("%d",&n);
for(int i=1;i<=n;i++)
{
int tt;
scanf("%d",&tt);
build(i,tt);
}
for(int i=1;i<=n;i++)
{
if(!dfn[i]) dfs(i);
}
cout<return 0;
}
倍增lca+树上前缀和:
#include
#include
#include
#include
using namespace std;
const int MAXN=50000+10;
int first[MAXN],nxt[MAXN<<1],dis[MAXN];
struct edge{
int from,to,cost;
}es[MAXN<<1];
int tot;
int deep[MAXN],fa[MAXN],father[MAXN][30];
void init()
{
memset(first,-1,sizeof(first));
memset(dis,0x3f,sizeof(dis));
tot=0;
}
void build(int ff,int tt,int dd)
{
es[++tot]=(edge){ff,tt,dd};
nxt[tot]=first[ff];
first[ff]=tot;
}
void dfs(int u, int f)
{
deep[u]=deep[f]+1;
fa[u]=f;
father[u][0]=f;
for(int i=1;i<=24;i++)
father[u][i]=father[father[u][i-1]][i-1];
for(int i=first[u];i!=-1;i=nxt[i])
{
int v=es[i].to;
if(v==f) continue;
dis[v]=dis[u]+es[i].cost;
dfs(v,u);
}
}
int lca(int x,int y)
{
if(deep[x]if(deep[x]>deep[y])
{
int t=deep[x]-deep[y];
for(int i=24;i>=0;i--)
if(t&(1<if(x!=y)
{
for(int i=24;i>=0;i--)
{
if(father[x][i]!=father[y][i])
{
x=father[x][i];
y=father[y][i];
}
}
}
else return x;
return father[x][0];
}
int main()
{
init();
int n;
scanf("%d",&n);
for(int i=1;iint ff,tt,dd;
scanf("%d%d%d",&ff,&tt,&dd);
build(ff,tt,dd);
build(tt,ff,dd);
}
int m;
scanf("%d",&m);
// deep[1]=1;
dfs(0,0);
int u,v;
for(int i=1;i<=m;i++)
{
int ans=0;
scanf("%d%d",&u,&v);
int x=lca(u,v);
//cout<
ans=dis[u]+dis[v]-dis[x]*2;
printf("%d\n",ans);
}
return 0;
}
拓扑排序:
#include
#include
#include
#include
#include
using namespace std;
const int SZ=100100;
int rd[SZ];
int ans,n,m;
struct edge{
int from,to;
}es[SZ];
int tot,first[SZ],nxt[SZ];
void build(int ff,int tt)
{
es[++tot]=(edge){ff,tt};
nxt[tot]=first[ff];
first[ff]=tot;
}
queue<int>q;
void sort()
{
for(int i=1;i<=n;i++)
if(!rd[i])
{
printf("%d ",i);
q.push(i);
}
while(!q.empty())
{
int u=q.front();q.pop();
for(int i=first[u];i!=-1;i=nxt[i])
{
int v=es[i].to;
rd[v]--;
if(!rd[v])
{
printf("%d ",v);
q.push(v);
}
}
}
}
int main()
{
while(~scanf("%d",&n))
{
memset(first,-1,sizeof(first));
int t;
for(int i=1;i<=n;i++)
{
while(scanf("%d",&t)&&t)
{
rd[t]++;
build(i,t);
}
}
sort();
}
return 0;
}