2011.07.29

POJ  1459  Power Network

        题意:电网系统中有发电站,用户和传输线路构成。每个电站有发电量,每个用户有用电需求,每条传输线路有最大负载值。问这个网络最多能满足多少用电需求。

        其实这就是果的最大流,新建源点s到np个发电站容量为发电量的弧,从发电站向相应用户作容量为线路最大负载的弧,从用户向新建汇点t作容量为用电需求的弧,求s-t最大流。

#include<cstdio>
#include<cstring>
#include<fstream>
#define MAXV 101
#define MAXE 10001
using namespace std;
const int inf=1<<31-1;
inline int min(int a,int b) {return a<b?a:b;}
int d[MAXV],vd[MAXV],head[MAXV];
int pos,m,n,s,t;
char ch[1000];
struct edge
{
    int v,f,next;
}e[MAXE*2];

void add(int u,int v,int c)
{
    e[pos].v=v;
    e[pos].f=c;
    e[pos].next=head[u];
    head[u]=pos++;
}
int dfs(int u,int flow)
{
    int ret=0,v,tmp;
    if(u==t) return flow;
    for(int i=head[u];i!=-1;i=e[i].next)if(e[i].f>0 && d[u]==d[e[i].v]+1)
    {
        tmp=dfs(e[i].v,min((flow-ret),e[i].f));
        e[i].f-=tmp;
        e[i+1].f+=tmp;
        ret+=tmp;
        if(ret==flow) return ret;
    }
    if(d[s]>n) return ret;
    vd[d[u]]--;
    if(vd[d[u]]==0) d[s]==n+1;
    d[u]++;
    vd[d[u]]++;
    return ret;
}
int main()
{
    int i,j,k,np,nc,u,v,f,flow,ans;
    while(EOF!=(scanf("%d%d%d%d",&n,&np,&nc,&m))){
        pos=1;s=n;t=++n;ans=0;
        memset(d,0,sizeof(d));
        memset(vd,0,sizeof(vd));
        memset(head,-1,sizeof(head));
        while(m--){
            scanf("%s",ch);
            sscanf(ch,"(%d,%d)%d",&u,&v,&f);
            add(u,v,f);
            add(v,u,0);
        }
        while(np--){
            scanf("%s",ch);
            sscanf(ch,"(%d)%d",&v,&f);
            add(s,v,f);
            add(v,s,0);
        }
        while(nc--){
            scanf("%s",ch);
            sscanf(ch,"(%d)%d",&u,&f);
            add(u,t,f);
            add(t,u,0);
        }
        vd[0]=n;
        while(d[s]<=n){
            flow=dfs(s,inf);
            ans+=flow;
        }
        printf("%d\n",ans);
    }
    return 0;
}


POJ  1149  Pigs

        题意:今天写程序累了给农场当猪倌~连给猪猪开门的钥匙都木有= =,好了工作开始吧~猪猪们住在不同的房纸里,房纸很大够无限只猪住的,不过里面现在只有一些猪。今天有n个人预约先后来买猪,第i个人有Ai把对应Ai个猪房纸的钥匙,和对猪的需求Bi,我就负责把猪赶出来给顾客。不过每次打开的Ai个房纸里的猪可以让它们换房纸住。这样的话最多能卖出多少头猪呢?

        好吧又是二分图中的网络流问题…昨天被那群二分图玩虐后今天觉得思路好不卡壳= =,建立源点s到顾客的弧,容量为顾客的需求量,建立顾客到他有钥匙的猪房纸的弧,容量为inf,建立猪房纸到汇点t的容量为房里猪数量的弧。然后就是我二的时候了:我想把所有开过的房纸和顾客之间建立容量inf的反向弧不就可以完成猪的迁移了,相当于顾客可以选择的房纸变多了嘛~这种想法本没什么错,错就错在没注意到顾客来时有先后…先后……也就是说只有先来的顾客打开过的房纸和现在的顾客手里有钥匙的房纸才能打开……所以那个方案是有问题的,换个思路考虑,把已经打开过的猪房纸放进一个集合,之后做的事就是给这个集合不断增加元素而已,有点类似并查集的思路。容易实现的方法是从后一个顾客给先前和他有相同钥匙的顾客连一条弧,容量为inf,这样完成建图,然后最大流即可。说下刚刚的问题只wa了一遍…然后是m和n写反了wa了无数遍lol……细心啊少年!!

#include<cstdio>
#include<cstring>
#include<fstream>
#define MAXV 5000
#define MAXE 100000
using namespace std;
const int inf=1<<31-1;
inline int min(int a,int b) {return a<b?a:b;}
int d[MAXV],vd[MAXV],head[MAXV],pre[MAXV];
int pos,m,n,s,t,V,E;
char ch[1000];
struct edge
{
    int v,f,next;
}e[MAXE*2];

void add(int u,int v,int c)
{
    e[pos].v=v;
    e[pos].f=c;
    e[pos].next=head[u];
    head[u]=pos++;
}
int dfs(int u,int flow)
{
    int ret=0,v,tmp;
    if(u==t) return flow;
    for(int i=head[u];i!=-1;i=e[i].next)if(e[i].f>0 && d[u]==d[e[i].v]+1)
    {
        tmp=dfs(e[i].v,min((flow-ret),e[i].f));
        e[i].f-=tmp;
        e[i+1].f+=tmp;
        ret+=tmp;
        if(ret==flow) return ret;
    }
    if(d[s]>V) return ret;
    vd[d[u]]--;
    if(vd[d[u]]==0) d[s]=V;
    d[u]++;
    vd[d[u]]++;
    return ret;
}
int main()
{
    int i,j,k,np,nc,u,v,w,f,flow,ans;
    	scanf("%d%d",&m,&n);
        pos=1;s=m+n+1;t=s+1;ans=0;
        V=m+n+2;
        memset(head,-1,sizeof(head));
        for(i=1;i<=m;i++){
            scanf("%d",&w);
            add(n+i,t,w);add(t,n+i,0);
        }
        for(i=1;i<=n;i++){
            scanf("%d",&k);
            for(j=1;j<=k;j ++){
                scanf("%d",&v);
                add(i,v+n,inf);add(v+n,i,0);
            	if(pre[v+n]!=0){ 
			        add(i,pre[v+n],inf);add(pre[v+n],i,0);}
            	pre[v+n]=i;
            }
            scanf("%d",&w);
            add(s,i,w);add(i,s,0);
        }
        vd[0]=V;
        while(d[s]<V){
            flow=dfs(s,inf);
            ans+=flow;
        }
        printf("%d\n",ans);
    return 0;
}

        今天DIY又被虐爆了…图论各种搜索各种搜,ORZ,也打算明天解决。

        郝师傅回来了,说跟教授吵架的…又对实验室卫生很不满意,郝师傅是喜欢干净的家伙啦~可是这样他一定更不开心了吧…他刚走就初具乱象的样子,一定更不开心了吧……可是郝师傅还是笑着跟大家说了好多,还提着那么沉的旅行箱爬上了五楼,大概是想最后见一见我们这帮家伙吧……

        听过不少人说郝师傅脾气好差了,可是我不觉得啊~厉害的家伙总是有趣的,有趣的家伙总是和群体不太相容的,我固执的这么认为。其实郝师傅的心是很柔软那种,对身边的人和这个世界很多关怀。不过这样不代表不执着,他对自由很执着,又对秩序很执着,这样会不会很矛盾呢?大概有他自己的想法吧,不过我没机会知道了吧……

        要走时,郝师傅问你有没有什么想跟我说的,其实有啊,我想说我会想你的,不过没说出来,这种东西说不说不重要吧,被当成误会会比较讨厌啊~最不喜欢有人离开了,实验室里我最喜欢说话的家伙要走了…想起上个学期一起从漫画聊到道德经,一起分享食物的日子,郝师傅甚至把SSH告诉我的日子,就像在昨天一样啊~为什么转眼,就要走了呢?为了自己的路吧~祝郝师傅肉翻成功,郝师傅和好师母一起和和美美,看这两个个子小小的家伙在一起真是各种开心呢~


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值