1 条题解

  • 0
    @ 2025-5-28 12:57:50

    问题分析

    1. 将电路建模为有向无环图(DAG)
    2. 电流流动形成网络流
    3. 需要满足所有元件的电流需求

    关键点

    • 元件电流约束
    • 节点电流平衡
    • 无循环路径

    解题步骤

    1. 构建网络流图:
      • 源点:正极端子+
      • 汇点:负极端子-
      • 元件作为有向边(容量=所需电流)
    2. 计算最小可行流:
      • 使用最大流算法
      • 检查是否所有边流量满足下限
    
    #include<stdio.h>
    #include<string.h>
    #define inf 0x7fffffff
    struct edge//边  
    {  
        int u,v,f,next,b,c;//边的 前节点 后节点 可用流 下条边的编号  原来边上流的上下界  
    }e[1500];  
    int head[70],in[70],s,t,ss,tt,yong,sum;
    int n,m;
    void ini()
    {
    	memset(head,-1,sizeof(head));
    	yong=0;
    	memset(in,0,sizeof(in));
    	s=0,t=n+1,ss=t+1,tt=ss+1;//各节点编号的安排
    	sum=0;
    }
    void adde(int from,int to,int xia,int shang)//加边  
    {	//加边  
        e[yong].u=from,e[yong].v=to,e[yong].f=shang-xia,e[yong].b=xia,e[yong].c=shang;  
        e[yong].next=head[from],head[from]=yong++;  
    	//同时加它的退边  
        e[yong].u=to,e[yong].v=from,e[yong].f=0,e[yong].b=xia,e[yong].c=shang;  
        e[yong].next=head[to],head[to]=yong++;  
    } 
    void build()
    {
    	int i;  
        for(i=0;i<=t;++i)  
        {  
            if(in[i]>0)  
                adde(ss,i,0,in[i]);  
            else  
            {  
                adde(i,tt,0,-in[i]);  
                sum+=(-in[i]);  
            }  
        } 
    }
    int d[1000],num[1000];
    int min(int a,int b){return a<b?a:b;}  
    int sap_gap(int u,int f,int s,int t)//递归sap  
    {  
        if(u==t)  
            return f;  
        int i,v,mind=t,last=f,cost;  
        for(i=head[u];i!=-1;i=e[i].next)  
        {  
            v=e[i].v;  
            int flow=e[i].f;  
            if(flow>0)//参考模版写的时候把flow写成了f  
            {  
                if(d[u]==d[v]+1)  
                {  
                    cost=sap_gap(v,min(last,flow),s,t);  
                    e[i].f-=cost;  
                    e[i^1].f+=cost;  
                    last-=cost;  
      
                    if(d[s]>=t+1)  
                        return f-last;  
      
                    if(last==0)  
                        break;  
                }  
                if(d[v]<mind)  
                    mind=d[v];  
            }  
        }  
      
        if(last==f)  
        {  
            --num[d[u]];  
            if(num[d[u]]==0)  
                d[s]=t+1;  
            d[u]=mind+1;  
            ++num[d[u]];  
        }  
        return f-last;  
    }  
    int max_f(int s,int t)
    {
        int f=0;  
        memset(d,0,sizeof(d));  
        memset(num,0,sizeof(num));  
        for(num[s]=t+1;d[s]<t+1;)  
            f+=sap_gap(s,inf,s,t);  
        return f; 
    }
    int main()
    {
    	int i,dat,u,v,f1,f2,p;
    	char from[10],to[10];
    	while(scanf("%d%d",&n,&m),n+m)
    	{
    		ini();
    		for(i=1;i<=m;++i)
    		{
    			scanf("%s%s%d",from,to,&dat);
    			if(from[0]=='+') u=s;
    			else sscanf(from,"%d",&u);
    			if(to[0]=='-') v=t;
    			else sscanf(to,"%d",&v);
    			adde(u,v,dat,inf);
    			in[u]-=dat,in[v]+=dat;
    		}
    		build();
     
    		f1=max_f(ss,tt);
    		p=yong;
    		adde(t,s,0,inf);
    		f2=max_f(ss,tt);
    		if(f1+f2!=sum) printf("impossible\n");
    		else printf("%d\n",e[p^1].f);
    	}
    	return 0;
    }
    
    • 1

    信息

    ID
    2801
    时间
    1000ms
    内存
    256MiB
    难度
    10
    标签
    递交数
    1
    已通过
    1
    上传者