Noip复习 图论代码整理
最小生成树
Prim+heap:
typedef pair <ll, int>P;
void prim()
{
priority_queue<P, vector<P>, greater<P> >que;
que.push(P(0,1));
while (!que.empty())
{
P s=que.top();
que.pop();
int v=s.second;
if (cost[v]<s.first) continue;
hh+=s.first;
vis[v]=1;
for (int i=1; i<=n; i++){
if (!vis[i] && cost[i]>map[v][i] && map[v][i]>0){
cost[i]=map[v][i];
que.push(P(cost[i], i));
}
}
}
}
Kruskal:
int bfind(int x)
{
if (f[x]==x) return x;
f[x]=bfind(f[x]);
return f[x];
}
void bunion(int x, int y)
{
int x1=bfind(x);
int y1=bfind(y);
f[x1]=y1;
}
bool cmp(Edge a, Edge b)
{
return a.val<b.val;
}
void kruskal()
{
int i=1;
int j=0;
int v1, v2;
sort(s+1, s+side+1, cmp);
while (i<side)
{
v1=bfind(s[i].s);
v2=bfind(s[i].t);
if (v1!=v2)
{
bunion(v1, v2);
hh+=s[i].val;
if (++j==n-1) break;
}
i++;
}
}
最短路径
Dijkstra:
struct edge{int to, cost};
typedef pair <ll, int>P; //first为最短距离,second是顶点;
int V;
vector<edge>G[MAX_N];
int d[MAX_V];
void dijkstra(int s){
priority_queue<P, vector<P>, greater<P> >que;
fill(d, d+V, INF);
d[s]=0;
que.push(P(0,s));
while (!que.empty())
{
P p=que.top();
que.pop();
int v=p.second;
if (d[v]<p.first) continue;
for (int i=0; i<G[v].size; i++){
edge e=G[v][i];
if (d[e.to]>d[v]+e.cost){
d[e.to]-d[v]+e.cost;
que.push(P(d[e.to], e.to));
}
}
}
SPFA:
void solve()
{
flag=1;
queue <int>q;
d[1]=0;
co[1]++;
q.push(1);
vis[1]=1;
while (!q.empty())
{
int v=q.front();
q.pop();
for (int i=1; i<=n; i++)
{
if (d[v]+map[v][i]<d[i])
{
d[i]=d[v]+map[v][i];
co[i]++;
if (co[i]>n-1)
{
flag=0;
return;
}
if (!vis[i])
{
vis[i]=1;
q.push(i);
}
}
}
vis[v]=0;
}
}
其他
拓扑排序:
void toposort()
{
int nn=0;
for (int i=1; i<=n; i++)
{
if (!co[i]) s.push(i);
}
if (s.empty()){
printf("No sort\n");
return;
}
else
{
while (!s.empty())
{
tj++;
int v=s.top();
a[++nn]=v;
s.pop();
for (linklist *i=map[v].next; i!=NULL; i=i->next)
{
co[i->s]--;
if(!co[i->s]) s.push(i->s);
}
}
}
}
关键路径:
void toposort()
{
int tj=0;
for (int i=1; i<=n; i++) if (!co[i]) s1.push(i);
if (s1.empty()) {
flag=0;
return;
}
else
{
while (!s1.empty())
{
tj++;
int v=s1.top();s2.push(v);
co[v]=n+1;
s1.pop();
for (linklist *j=map[v].next; j!=NULL; j=j->next)
{
int t=j->s;
co[t]--;
if (!co[t]) s1.push(t);
if (etv[v]+j->w > etv[t]) etv[t]=etv[v]+j->w;
}
}
}
if (tj<n) {
flag=0;
return;//check the cycle;
}
}
void solve()
{
toposort();
if (!flag) return;
for (int i=1; i<=n; i++) ltv[i]=etv[n];
while (!s2.empty())
{
int v=s2.top();
s2.pop();
for (linklist *j=fmap[v].next; j!=NULL; j=j->next)
{
int t=j->s;
if (ltv[v]-j->w < ltv[t]) ltv[t]=ltv[v]-j->w;
}
}
debug();
}
数据结构:链表
void insert(linklist &x, int y, int val)
{
linklist *t;
t=new(linklist);
t->val=val;
t->s=y;
t->next=x.next;
x.next=t;
}
void init()for (int i=1; i<=n; i++)
{
map[i].s=i;
map[i].next=NULL;
map[i].w=0;
fmap[i].s=i;
fmap[i].next=NULL;
fmap[i].w=0;
}
for (int i=1; i<=m; i++)
{
int x, y, val;
scanf("%d %d %d", &x, &y, &val);
insert(map[x], y, val);
insert(fmap[y], x, val);
co[y]++;
}