2016夏季练习——最小树形图
2016-07-27 21:30
337 查看
来源:HDU4966
终于见识到了传说中的建图问题,建图建的真是666啊。。。
代码:
#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
const int INF = 0x3f3f3f3f;
const int MAXN = 555;
const int MAXE = 2555;
struct Edge{
int u,v;
int w;
}edge[MAXE];
int level[60][510];
int des[60];
int pre[MAXE],id[MAXE],vis[MAXE],in[MAXE];
int zhuliu(int root,int n,int m){
int ans = 0;
int v,u;
while(1){
for(int i=0;i<n;i++)
in[i] = INF;
for(int i=0;i<m;i++){
u = edge[i].u;
v = edge[i].v;
if(u!=v&&in[v]>edge[i].w){
pre[v]=u;
in[v]=edge[i].w;
}
}
for(int i=0;i<n;i++){
if(i!=root&&in[i]==INF)
return -1;
}
int tn = 0;
memset(id,-1,sizeof(id));
memset(vis,-1,sizeof(vis));
in[root] = 0;
for(int i=0;i<n;i++){
ans+=in[i];
v = i;
while(vis[v]!=i&&v!=root&&id[v]==-1){
vis[v] = i;
v = pre[v];
}
if(v!=root&&id[v]==-1){
for(u = pre[v];u!=v;u=pre[u]){
id[u] = tn;
}
id[v] = tn++;
}
}
if(tn==0) {
return ans;
}
for(int i=0;i<n;i++){
if(id[i]==-1) id[i]=tn++;
}
for(int i=0;i<m;i++){
v = edge[i].v;
edge[i].u = id[edge[i].u];
edge[i].v = id[edge[i].v];
if(edge[i].v!=edge[i].u)
edge[i].w -= in[v];
}
n = tn;
root = id[root];
}
return ans;
}
int main(){
int n,m;
int ID;
while(scanf("%d%d",&n,&m)!=EOF){
if(m==0&&n==0) break;
ID=1;
for(int i=1;i<=n;i++){
scanf("%d",&des[i]);
for(int j=0;j<=des[i];j++){
level[i][j]=ID++;
}
}
int c,L1,d,L2,w;
int cnt=0;
for(int i=0;i<m;i++){
scanf("%d%d%d%d%d",&c,&L1,&d,&L2,&w);
edge[cnt].u=level[c][L1];
edge[cnt].v=level[d][L2];
edge[cnt++].w=w;
}
for(int i=1;i<=n;i++){
for(int j=1;j<=des[i];j++){
edge[cnt].v=level[i][j-1];
edge[cnt].u=level[i][j];
edge[cnt++].w=0;
}
}
for(int i=1;i<=n;i++){
edge[cnt].u = 0;
edge[cnt].v = level[i][0];
edge[cnt++].w = 0;
}
n = ID;//刚好加上0点
cout<<zhuliu(0,n,cnt)<<endl;
}
return 0;
}
终于见识到了传说中的建图问题,建图建的真是666啊。。。
代码:
#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
const int INF = 0x3f3f3f3f;
const int MAXN = 555;
const int MAXE = 2555;
struct Edge{
int u,v;
int w;
}edge[MAXE];
int level[60][510];
int des[60];
int pre[MAXE],id[MAXE],vis[MAXE],in[MAXE];
int zhuliu(int root,int n,int m){
int ans = 0;
int v,u;
while(1){
for(int i=0;i<n;i++)
in[i] = INF;
for(int i=0;i<m;i++){
u = edge[i].u;
v = edge[i].v;
if(u!=v&&in[v]>edge[i].w){
pre[v]=u;
in[v]=edge[i].w;
}
}
for(int i=0;i<n;i++){
if(i!=root&&in[i]==INF)
return -1;
}
int tn = 0;
memset(id,-1,sizeof(id));
memset(vis,-1,sizeof(vis));
in[root] = 0;
for(int i=0;i<n;i++){
ans+=in[i];
v = i;
while(vis[v]!=i&&v!=root&&id[v]==-1){
vis[v] = i;
v = pre[v];
}
if(v!=root&&id[v]==-1){
for(u = pre[v];u!=v;u=pre[u]){
id[u] = tn;
}
id[v] = tn++;
}
}
if(tn==0) {
return ans;
}
for(int i=0;i<n;i++){
if(id[i]==-1) id[i]=tn++;
}
for(int i=0;i<m;i++){
v = edge[i].v;
edge[i].u = id[edge[i].u];
edge[i].v = id[edge[i].v];
if(edge[i].v!=edge[i].u)
edge[i].w -= in[v];
}
n = tn;
root = id[root];
}
return ans;
}
int main(){
int n,m;
int ID;
while(scanf("%d%d",&n,&m)!=EOF){
if(m==0&&n==0) break;
ID=1;
for(int i=1;i<=n;i++){
scanf("%d",&des[i]);
for(int j=0;j<=des[i];j++){
level[i][j]=ID++;
}
}
int c,L1,d,L2,w;
int cnt=0;
for(int i=0;i<m;i++){
scanf("%d%d%d%d%d",&c,&L1,&d,&L2,&w);
edge[cnt].u=level[c][L1];
edge[cnt].v=level[d][L2];
edge[cnt++].w=w;
}
for(int i=1;i<=n;i++){
for(int j=1;j<=des[i];j++){
edge[cnt].v=level[i][j-1];
edge[cnt].u=level[i][j];
edge[cnt++].w=0;
}
}
for(int i=1;i<=n;i++){
edge[cnt].u = 0;
edge[cnt].v = level[i][0];
edge[cnt++].w = 0;
}
n = ID;//刚好加上0点
cout<<zhuliu(0,n,cnt)<<endl;
}
return 0;
}
相关文章推荐
- ECMAScript总结
- BFS-Oil Deposits
- DHCP Set Hostname
- 微信开发入门
- php设计模式之单例模式
- 记某次codeforces考试 A. Levko and Array Recovery
- js 的 深拷贝 和 浅拷贝
- JavaScript - 基于原型的面向对象
- Spring与远程调用RMI、Hessian、Burlap、HttpInvoker、Jax-WS
- php单例模式的常见应用场景
- 方便、强大的图片批量处理工具IrfanView:缩放、裁剪、做特效、加文字、自由翻转、改文件名
- Linux基础系列3(history命令)
- Spring boot 配置文件
- UVA 167 The Sultan's Successors
- Ionic2 Tutorial
- 第十七章 Lights
- HDU Problem 4004 The Frog's Games 【二分】
- **YII** 系列二yii的基本理解
- 第3章 开发支持
- HDU 1698 Just a Hook(线段树区间置换)