HDU2121 Ice_cream’s world II (最小树形图)

在建图的时候对原图进行加边 建立一个超级源点~

#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn=;
const int maxm=;
const int inf=1e9;
struct edge {
int u;
int v;
int w;
}Edge[maxm];
int pre[maxn];
int id[maxn];
int visit[maxn];
int in[maxn];
int N,M;
int root;
int pos;
int num;
void add (int u,int v,int w) {
Edge[num].u=u;
Edge[num].v=v;
Edge[num++].w=w;
}
int solve () {
int ans=;
while () {
for (int i=;i<N;i++) in[i]=inf;
for (int i=;i<num;i++) {
int u=Edge[i].u;
int v=Edge[i].v;
if (Edge[i].w<in[v]&&u!=v) {
pre[v]=u;
in[v]=Edge[i].w;
if (u==root) pos=i;
}
}
for (int i=;i<N;i++) {
if (i!=root&&in[i]==inf) return -;
}
int tn=;
memset(id,-,sizeof(id));
memset(visit,-,sizeof(visit));
in[root]=;
for (int i=;i<N;i++) {
ans+=in[i];
int v=i;
while (visit[v]!=i&&id[v]==-&&v!=root) {
visit[v]=i;
v=pre[v];
}
if (v!=root&&id[v]==-) {
for (int u=pre[v];u!=v;u=pre[u])
id[u]=tn;
id[v]=tn++;
}
}
if (tn==) break;
for (int i=;i<N;i++) {
if (id[i]==-) id[i]=tn++;
}
for (int i=;i<num;i++) {
int v=Edge[i].v;
Edge[i].u=id[Edge[i].u];
Edge[i].v=id[Edge[i].v];
if (Edge[i].u!=Edge[i].v) Edge[i].w-=in[v];
}
N=tn;
root=id[root];
}
return ans;
}
int main () {
while (~scanf("%d%d",&N,&M)) {
int sum=;
num=;
for (int i=;i<M;i++) {
int u,v,w;
scanf ("%d %d %d",&u,&v,&w);
sum+=w;
add(u,v,w);
}
sum++;
for (int i=;i<N;i++) {
add(N,i,sum);
}
N++;
root=N-;
int ans=solve();
if (ans==-||ans>=*sum) {
printf ("impossible\n");
}
else printf ("%d %d\n",ans-sum,pos-M);
printf ("\n");
}
return ;
}
上一篇:Sublime Text Snippets(代码片段)功能


下一篇:openssl可以实现:秘钥证书管理、对称加密和非对称加密