朱刘算法
前言
这只是一个用来存板子的地方
貌似这个东西除了做板题就没用了
练习
代码
板题1代码
struct edge
{
int u,v,w;
edge(){}
edge(int u1,int v1,int w1){
u = u1;
v = v1;
w = w1;
}
}e[MAXM];
int in[MAXN],pre[MAXN],vis[MAXN],ID[MAXN];
int zhuliu()
{
int ret = 0;
while(1)
{
for(int i = 1;i <= n;++ i) in[i] = INF;
for(int i = 1;i <= m;++ i)
if(e[i].w < in[e[i].v])
in[e[i].v] = e[i].w,pre[e[i].v] = e[i].u;
for(int i = 1;i <= n;++ i) if(i != rt && in[i] == INF) return -1;
int cnt = 0,tmp = 0;
for(int i = 1;i <= n;++ i) vis[i] = ID[i] = 0;
for(int i = 1;i <= n;++ i)
{
if(i == rt) continue;
ret += in[i];
int now = i;
while(vis[now] != i && !ID[now] && now != rt)
{
vis[now] = i;
now = pre[now];
}
if(!ID[now] && now != rt)
{
ID[now] = ++cnt;
while(!ID[pre[now]]) now = pre[now],ID[now] = cnt;
}
}
if(!cnt) break;//无环
for(int i = 1;i <= n;++ i) if(!ID[i]) ID[i] = ++cnt;//不是环上的点
for(int i = 1;i <= m;++ i)
if(ID[e[i].u] != ID[e[i].v])
e[++tmp] = edge(ID[e[i].u],ID[e[i].v],e[i].w - in[e[i].v]);
rt = ID[rt];
n = cnt;
m = tmp;
}
return ret;
}
int main()
{
// freopen(".in","r",stdin);
// freopen(".out","w",stdout);
n = Read(); m = Read(); rt = Read();
for(int i = 1;i <= m;++ i)
{
e[i].u = Read();
e[i].v = Read();
e[i].w = Read();
if(e[i].u == e[i].v) m--,i--;
}
Put(zhuliu());
return 0;
}
板题2代码
用快读要T,真就用脚造数据?
struct edge
{
int u,v;
double w;
edge(){}
edge(int u1,int v1,double w1){
u = u1;
v = v1;
w = w1;
}
}e[MAXM];
struct node
{
int x,y;
}p[MAXN];
double dis(node a,node b) {return sqrt(1.0 * (a.x - b.x) * (a.x - b.x) + 1.0 * (a.y - b.y) * (a.y - b.y));}
int pre[MAXN],vis[MAXN],ID[MAXN];
double in[MAXN];
double zhuliu()
{
double ret = 0;
while(1)
{
for(int i = 1;i <= n;++ i) in[i] = INF;
for(int i = 1;i <= m;++ i)
if(e[i].w < in[e[i].v])
in[e[i].v] = e[i].w,pre[e[i].v] = e[i].u;
for(int i = 1;i <= n;++ i) if(i != rt && in[i] == INF) return -1;
int cnt = 0,tmp = 0;
for(int i = 1;i <= n;++ i) vis[i] = ID[i] = 0;
for(int i = 1;i <= n;++ i)
{
if(i == rt) continue;
ret += in[i];
int now = i;
while(vis[now] != i && !ID[now] && now != rt)
{
vis[now] = i;
now = pre[now];
}
if(!ID[now] && now != rt)
{
ID[now] = ++cnt;
while(!ID[pre[now]]) now = pre[now],ID[now] = cnt;
}
}
if(!cnt) break;
for(int i = 1;i <= n;++ i) if(!ID[i]) ID[i] = ++cnt;
for(int i = 1;i <= m;++ i)
if(ID[e[i].u] != ID[e[i].v])
e[++tmp] = edge(ID[e[i].u],ID[e[i].v],e[i].w - in[e[i].v]);
rt = ID[rt];
n = cnt;
m = tmp;
}
return ret;
}
int main()
{
// freopen(".in","r",stdin);
// freopen(".out","w",stdout);
while(~scanf("%d %d",&n,&m))
{
rt = 1;
for(int i = 1;i <= n;++ i) scanf("%d %d",&p[i].x,&p[i].y);
for(int i = 1;i <= m;++ i)
{
scanf("%d %d",&e[i].u,&e[i].v);
if(e[i].u == e[i].v) m--,i--;
else e[i].w = dis(p[e[i].u],p[e[i].v]);
}
double ans = zhuliu();
if(ans == -1) printf("poor snoopy\n");
else printf("%.2f\n",ans);
}
return 0;
}