标签:
HDNOIP201304阻断传染 |
难度级别: A; 编程语言:不限;运行时间限制:1000ms; 运行空间限制:51200KB; 代码长度限制:2000000B |
试题描述
|
H国有n个城市,n个城市用n-1条双向道路相互连通构成一棵树,1号城市是首都,也是树中的根节点。H国的首都爆发了一种危害性极高的传染病。当局为了控制疫情,不让疫情扩散到边境城市(叶子节点所表示的城市),决定在一些公路上设检疫关卡,但在不同道路上设卡的代价可能不同,为了防止边境城市受传染,必需让从首都到每个边境城市的路径上都至少有一个检疫关卡,请你编程求能阻止传染的最小设卡总代价。 |
输入
|
第一行一个整数 n,表示城市个数。
接下来的 n-1 行,每行 3 个整数,u、v、w,每两个整数之间用一个空格隔开,表示从城市u到城市v有一条双向道路,设卡代价为w。 数据保证输入的是一棵树,且根节点编号为1。 |
输出
|
其中共一行,包含一个整数,表示控制疫情所需要的最少设卡总代价。
|
输入示例
|
9
2 1 888 1 3 88 2 4 6 5 2 8 6 3 100 3 7 10 8 3 50 7 9 1 |
输出示例
|
102
|
其他说明
|
对于 60%的数据,2<n<10,对于 80%的数据,2<n<100,对于 100%的数据,2<n<100000
|
题解:直接写个最小割跑去吧。。。
Wa了两发是因为bfs得时候忘设vis[S]=true了。。。QAQ。。。
1 #include<iostream> 2 #include<cstdio> 3 #include<cmath> 4 #include<algorithm> 5 #include<queue> 6 #include<cstring> 7 #define PAU putchar(‘ ‘) 8 #define ENT putchar(‘\n‘) 9 using namespace std; 10 const int maxn=100000+10,maxm=200000+10,inf=-1u>>1; 11 int out[maxn]; 12 struct isap{ 13 struct ted{int x,y,w;ted*nxt,*re;}adj[maxm],*fch[maxn],*ms,*cur[maxn],*ret[maxn]; 14 int d[maxn],gap[maxn],n,S,T; 15 void init(int n){this->n=n;memset(d,-1,sizeof(d));ms=adj;return;} 16 void add(int x,int y,int w){ 17 *ms=(ted){x,y,w,fch[x],ms+1};fch[x]=ms++; 18 *ms=(ted){y,x,0,fch[y],ms-1};fch[y]=ms++; 19 return; 20 } 21 void bfs(){ 22 queue<int>Q;Q.push(T);d[T]=0; 23 while(!Q.empty()){ 24 int u=Q.front();Q.pop(); 25 for(ted*e=fch[u];e;e=e->nxt){ 26 int v=e->y;if(d[v]<0)d[v]=d[u]+1,Q.push(v); 27 } 28 } return; 29 } 30 int mxflow(int S,int T){ 31 this->S=S;this->T=T;bfs();ted*e;int k=S,flow=0; 32 for(int i=1;i<=n;i++)gap[d[i]]++,cur[i]=fch[i]; 33 while(d[S]<n){ 34 if(k==T){ 35 int mi=inf,pos;for(int i=S;i!=T;i=cur[i]->y)if(cur[i]->w<mi)mi=cur[i]->w,pos=i; 36 for(int i=S;i!=T;i=cur[i]->y)cur[i]->w-=mi,cur[i]->re->w+=mi;flow+=mi;k=pos; 37 } for(e=cur[k];e;e=e->nxt)if(e->w&&d[k]==d[e->y]+1)break; 38 if(e)cur[k]=e,ret[e->y]=e->re,k=e->y; 39 else{if(--gap[d[k]]==0)break;cur[k]=fch[k];int mi=n; 40 for(e=fch[k];e;e=e->nxt)if(e->w&&d[e->y]<mi)mi=d[e->y]; 41 d[k]=mi+1;gap[d[k]]++;if(k!=S)k=ret[k]->y; 42 } 43 } return flow; 44 } 45 }sol; 46 struct ted{int x,y,w;ted*nxt;}adj[maxm],*fch[maxn],*ms=adj; 47 void add(int x,int y,int w){ 48 *ms=(ted){x,y,w,fch[x]};fch[x]=ms++; 49 *ms=(ted){y,x,w,fch[y]};fch[y]=ms++; 50 return; 51 } 52 bool vis[maxn]; 53 void bfs(int S){ 54 queue<int>Q;Q.push(S);vis[S]=true; 55 while(!Q.empty()){ 56 int u=Q.front();Q.pop(); 57 for(ted*e=fch[u];e;e=e->nxt){ 58 int v=e->y;if(!vis[v]){ 59 vis[v]=true;out[u]++;sol.add(u,v,e->w);Q.push(v);//printf("add:%d->%d %d\n",u,v,e->w);system("pause"); 60 } 61 } 62 } return; 63 } 64 int n,m;queue<int>tset; 65 void makeG(){ 66 for(int i=1;i<=n;i++)if(!out[i])tset.push(i);//printf("tset:"); 67 while(!tset.empty()){ 68 int x=tset.front();tset.pop();sol.add(x,n+1,1e9);//printf("%d ",x); 69 } return; 70 } 71 inline int read(){ 72 int x=0,sig=1;char ch=getchar(); 73 while(!isdigit(ch)){if(ch==‘-‘) sig=-1;ch=getchar();} 74 while(isdigit(ch)) x=10*x+ch-‘0‘,ch=getchar(); 75 return x*=sig; 76 } 77 inline void write(int x){ 78 if(x==0){putchar(‘0‘);return;}if(x<0) putchar(‘-‘),x=-x; 79 int len=0,buf[15];while(x) buf[len++]=x%10,x/=10; 80 for(int i=len-1;i>=0;i--) putchar(buf[i]+‘0‘);return; 81 } 82 void init(){ 83 n=read();m=~-n;sol.init(n+1);int x,y,w; 84 for(int i=1;i<=m;i++){ 85 x=read();y=read();w=read();add(x,y,w); 86 }bfs(1);makeG();write(sol.mxflow(1,n+1)); 87 return; 88 } 89 void work(){ 90 return; 91 } 92 void print(){ 93 return; 94 } 95 int main(){ 96 init();work();print();return 0; 97 }
标签:
原文地址:http://www.cnblogs.com/chxer/p/4640504.html