POJ2396_Budget

解决矩形数字阵满足条件的流量分配问题
本文探讨如何使用流量分配算法解决给定矩形数字阵中,通过调整边权重满足特定条件的问题。文章详细介绍了构建图、边界处理、流量限制以及最终检查流程。通过实例演示了解决方案,确保所有约束条件得以满足。

题意为给一个矩形数字阵,给出一些限制条件,包括每行和每列的和,还有一些位置的数值范围,求出满足情况的一个。

首先建图,源点->行和->列和->汇点,显然,行和列之间的边为那个数字的大小,只要我们能够找到一个满足大小条件的,且使的两边的和满流的流量方案就可以了。

由于存在下界(上界其实就是边的容量),根据图的特殊性,我们可以先在那边的相连的两条边都减去这个下界,这样就变成了一条只有上界的边了。

 

 

召唤代码君:

 

 

#include <iostream>
#include <cstring>
#include <cstdio>
#define maxn 1022
#define maxm 844442
typedef long long ll;
using namespace std;

const ll inf=~0U>>1;
ll to[maxm],next[maxm],c[maxm],first[maxn],edge;
ll fmin[maxn][maxn],fmax[maxn][maxn],sr[maxn],sc[maxn];
ll d[maxn],tag[maxn],TAG=222;
ll Q[maxm],bot,top;
ll ans[maxn][maxn];
bool can[maxn];
ll n,m,s,t,T,R,sumr,sumc;

void _init()
{
    s=0,t=n+m+1,edge=-1,sumr=sumc=0;
    for (ll i=s; i<=t; i++) first[i]=-1;
    for (ll i=1; i<=n; i++) sr[i]=0;
    for (ll i=1; i<=m; i++) sc[i]=0;
    for (ll i=1; i<=n; i++)
        for (ll j=1; j<=m; j++) ans[i][j]=0,fmin[i][j]=0,fmax[i][j]=inf;
}

void minsize(ll x,ll y,ll dn,ll up)
{
    fmin[x][y]=max(fmin[x][y],dn);
    fmax[x][y]=min(fmax[x][y],up);
}

bool check()
{
    for (ll i=1; i<=n; i++)
        for (ll j=1; j<=m; j++)
            {
                if (fmax[i][j]<0) return false;
                sr[i]-=fmin[i][j],sc[j]-=fmin[i][j];
                sumr-=fmin[i][j],sumc-=fmin[i][j];
                fmax[i][j]-=fmin[i][j];
                if (fmax[i][j]<0 || sr[i]<0 || sc[j]<0) return false;
            }
    return sumr==sumc;
}

void addedge(ll U,ll V,ll W)
{
    edge++;
    to[edge]=V,c[edge]=W,next[edge]=first[U],first[U]=edge;
    edge++;
    to[edge]=U,c[edge]=0,next[edge]=first[V],first[V]=edge;
}

bool bfs()
{
    Q[bot=top=1]=t,tag[t]=++TAG,d[t]=0,can[t]=false;
    while (bot<=top)
    {
        ll cur=Q[bot++];
        for (ll i=first[cur]; i!=-1; i=next[i])
            if (c[i^1] && tag[to[i]]!=TAG)
            {
                tag[to[i]]=TAG,d[to[i]]=d[cur]+1;
                can[to[i]]=false,Q[++top]=to[i];
                if (to[i]==s) return true;
            }
    }
    return false;
}

ll dfs(ll cur,ll num)
{
    if (cur==t) return num;
    ll tmp=num,k;
    for (ll i=first[cur]; i!=-1; i=next[i])
        if (c[i] && d[to[i]]==d[cur]-1 && tag[to[i]]==TAG && !can[to[i]])
        {
            k=dfs(to[i],min(c[i],num));
            if (k) num-=k,c[i]-=k,c[i^1]+=k;
            if (!num) break;
        }
    if (num) can[cur]=true;
    return tmp-num;
}

ll maxflow()
{
    ll tot=0;
    while (bfs()) tot+=dfs(s,~0U>>1);
    return tot;
}

int main()
{
    char S[3];
    ll x,y,z,cas=0,up,dn;
    scanf("%I64d",&T);
    while (T--)
    {
        scanf("%I64d%I64d",&n,&m);
        _init();
        for (ll i=1; i<=n; i++) scanf("%I64d",&sr[i]),sumr+=sr[i];
        for (ll i=1; i<=m; i++) scanf("%I64d",&sc[i]),sumc+=sc[i];
        scanf("%I64d",&R);
        while (R--)
        {
            scanf("%I64d%I64d%s%I64d",&x,&y,S,&z);
            if (S[0]=='=') up=z,dn=max(0LL,z);
                else if (S[0]=='>') up=inf,dn=max(0LL,z+1);
                    else up=z-1,dn=0;
            if (x==0 && y==0)
            {
                for (ll i=1; i<=n; i++)
                    for (ll j=1; j<=m; j++) minsize(i,j,dn,up);
            }
            else if (x==0)
            {
                for (ll i=1; i<=n; i++) minsize(i,y,dn,up);
            }
            else if (y==0)
            {
                for (ll j=1; j<=m; j++) minsize(x,j,dn,up);
            }
            else minsize(x,y,dn,up);
        }
        if (cas++) puts("");
        if (!check())
        {
            puts("IMPOSSIBLE");
            continue;
        }
        for (ll i=1; i<=n; i++) addedge(s,i,sr[i]);
        for (ll j=1; j<=m; j++) addedge(n+j,t,sc[j]);
        for (ll i=1; i<=n; i++)
            for (ll j=1; j<=m; j++)
                if (fmax[i][j]>0) addedge(i,n+j,fmax[i][j]);
        /*        
        for (int i=1; i<=n; i++)
        {
            cout<<" hehe : ";
            for (int j=1; j<=m; j++) cout<<fmin[i][j]<<"("<<fmax[i][j]<<") ... ";
            cout<<endl;
        }
        */
        if (maxflow()!=sumr)
        {
            puts("IMPOSSIBLE");
            continue;
        }
        for (ll i=n+n+m+m; i<=edge; i+=2)
        {
            x=to[i+1],y=to[i]-n;
            ans[x][y]=c[i+1];
        }
        for (ll i=1; i<=n; i++)
        {
            printf("%I64d",ans[i][1]+fmin[i][1]);
            for (ll j=2; j<=m; j++) printf(" %I64d",ans[i][j]+fmin[i][j]);
            printf("\n");
        }
    } 
    return 0;
}

 

转载于:https://www.cnblogs.com/lochan/p/3870725.html

在车辆工程中,悬架系统的性能评估和优化一直是研究的热点。悬架不仅关乎车辆的乘坐舒适性,还直接影响到车辆的操控性和稳定性。为了深入理解悬架的动态行为,研究人员经常使用“二自由度悬架模型”来简化分析,并运用“传递函数”这一数学工具来描述悬架系统的动态特性。 二自由度悬架模型将复杂的车辆系统简化为两个独立的部分:车轮和车身。这种简化模型能够较准确地模拟出车辆在垂直方向上的运动行为,同时忽略了侧向和纵向的动态影响,这使得工程师能够更加专注于分析与优化与垂直动态相关的性能指标。 传递函数作为控制系统理论中的一种工具,能够描述系统输入和输出之间的关系。在悬架系统中,传递函数特别重要,因为它能够反映出路面不平度如何被悬架系统转化为车内乘员感受到的振动。通过传递函数,我们可以得到一个频率域上的表达式,从中分析出悬架系统的关键动态特性,如系统的振幅衰减特性和共振频率等。 在实际应用中,工程师通过使用MATLAB这类数学软件,建立双质量悬架的数学模型。模型中的参数包括车轮质量、车身质量、弹簧刚度以及阻尼系数等。通过编程求解,工程师可以得到悬架系统的传递函数,并据此绘制出传递函数曲线。这为评估悬架性能提供了一个直观的工具,使工程师能够了解悬架在不同频率激励下的响应情况。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值