UVALive 6129 Sofa, So Good

注意题意为先满足第一种操作总花费时间最小,在进行第二次操作并满足总时间最小。 两次二分图最大权匹配,第一次从工人到沙发连边,权值为第一次操作花费时间,第二次从沙发到工人连边,权值为工人开始工作的时间加上第二次操作的时间。 本人采用费用流写法,最后从残余网络找到答案。

#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>
#include<queue>
using namespace std;
const int inf=1010101010;
int S,T;
int a[60][60];
int b[60][60];
int n;
struct Edge
{
    int v,c,w,next;
}e[2000000];
int head[30000],cnt;
void addedge(int u,int v,int c,int w)
{
    e[cnt].v=v;
    e[cnt].c=c;
    e[cnt].w=w;
    e[cnt].next=head[u];
    head[u]=cnt++;
    e[cnt].v=u;
    e[cnt].c=0;
    e[cnt].w=-w;
    e[cnt].next=head[v];
    head[v]=cnt++;
}
int dis[100010];
bool vis[1010];
int pre[100010];
int pos[100010];
int mcmf()
{
     int ans=0; int maxflow=0;
     while(1){
      for(int i=0;i<=T;i++) dis[i]=inf,vis[i]=0,pre[i]=i,pos[i]=0;
      queue<int> q;
      dis[S]=0;
      q.push(S);
      vis[S]=1;
      int u,v,w,c;

        while(!q.empty())
        {
            u=q.front();
            q.pop();
            vis[u]=0;
            for(int i=head[u];i!=-1;i=e[i].next)
            {
                v=e[i].v;
                if(e[i].c>0&&dis[v]>dis[u]+e[i].w)
                {

                    pre[v]=u;
                    pos[v]=i;
                    dis[v]=dis[u]+e[i].w;
                    if(!vis[v])
                    {
                        vis[v]=1;
                        q.push(v);
                    }

                }
            }

         }
         if(dis[T]==inf) break;
         int sum=inf;
         for(u=T;u!=S;u=pre[u])
         {
             c=e[pos[u]].c;
             sum=min(sum,c);
         }
         maxflow+=sum;
         for(u=T;u!=S;u=pre[u])
         {
             e[pos[u]].c-=sum;
             e[pos[u]^1].c+=sum;
             ans+=sum*e[pos[u]].w;
         }
     }
       return ans;
}
int ans1[60];
int ans2[60];
vector<int> wo[60];
int main()
{
    int cas=1;
    while(~scanf("%d",&n))
    {
        if(n==0)return 0;
        memset(head,-1,sizeof(head));
        cnt=0;
        for(int i=1;i<=n;i++)
            wo[i].clear();
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
               scanf("%d",&a[i][j]);
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
                scanf("%d",&b[i][j]);
        S=n+n+1;
        T=S+1;
        for(int i=1;i<=n;i++)
            {addedge(S,i,1,0);addedge(i+n,T,1,0);}
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=n;j++)
            {
                addedge(i,j+n,1,a[i][j]);
            }
        }
        mcmf();
        for(int i=1+n;i<=n+n;i++)
        {
            for(int j=head[i];j!=-1;j=e[j].next)
            {
                if(e[j].c>0)
                {
                   int v=e[j].v;
                   //cout<<v<<" ll"<<endl;
                   wo[v].push_back(i-n);
                   ans1[i-n]=v;
                   ans2[v]=i-n;
                }
            }
        }
        memset(head,-1,sizeof(head));cnt=0;
        S=n+n+1;
        T=S+1;
        for(int i=1;i<=n;i++)
            addedge(S,i,1,0);
        for(int i=n+1;i<=n+n;i++)
            addedge(i,T,1,0);
        int tmp=0;
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=n;j++)
            {
                tmp=max(a[ans1[i]][i],a[j][ans2[j]]);
                addedge(i,n+j,1,tmp+b[j][i]);
            }
        }
        mcmf();int sum=0;
        for(int i=1+n;i<=n+n;i++)
        {
            for(int j=head[i];j!=-1;j=e[j].next)
            {
                if(e[j].c>0)
                {
                   int v=e[j].v;
                   wo[i-n].push_back(v);
                   int w=-e[j].w;
                   wo[i-n].push_back(w);
                   //cout<<i-n<<" "<<ans2[i-n]<< " "<<wo[i-n][1]<<endl;
                   if(w>a[i-n][ans2[i-n]]+b[i-n][wo[i-n][1]])
                    sum+=w-a[i-n][ans2[i-n]]-b[i-n][wo[i-n][1]];
                   //ans1[i-n]=v;
                   //ans2[v]=i-n;
                }
            }
        }

        printf("Case %d:\n",cas++);
        for(int i=1;i<=n;i++)
        {
            printf("Worker %d: %d %d %d\n",i,wo[i][0],wo[i][1],wo[i][2]);

        }printf("Total idle time: %d\n",sum);
    }
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
基于PyTorch的Embedding和LSTM的自动写诗实验LSTM (Long Short-Term Memory) 是一种特殊的循环神经网络(RNN)架构,用于处理具有长期依赖关系的序列数据。传统的RNN在处理长序列时往往会遇到梯度消失或梯度爆炸的问题,导致无法有效地捕捉长期依赖。LSTM通过引入门控机制(Gating Mechanism)和记忆单元(Memory Cell)来克服这些问题。 以下是LSTM的基本结构和主要组件: 记忆单元(Memory Cell):记忆单元是LSTM的核心,用于存储长期信息。它像一个传送带一样,在整个链上运行,只有一些小的线性交互。信息很容易地在其上保持不变。 输入门(Input Gate):输入门决定了哪些新的信息会被加入到记忆单元中。它由当前时刻的输入和上一时刻的隐藏状态共同决定。 遗忘门(Forget Gate):遗忘门决定了哪些信息会从记忆单元中被丢弃或遗忘。它也由当前时刻的输入和上一时刻的隐藏状态共同决定。 输出门(Output Gate):输出门决定了哪些信息会从记忆单元中输出到当前时刻的隐藏状态中。同样地,它也由当前时刻的输入和上一时刻的隐藏状态共同决定。 LSTM的计算过程可以大致描述为: 通过遗忘门决定从记忆单元中丢弃哪些信息。 通过输入门决定哪些新的信息会被加入到记忆单元中。 更新记忆单元的状态。 通过输出门决定哪些信息会从记忆单元中输出到当前时刻的隐藏状态中。 由于LSTM能够有效地处理长期依赖关系,它在许多序列建模任务中都取得了很好的效果,如语音识别、文本生成、机器翻译、时序预测等。
使用Go语言开发分布式应用,可以通过SofaGo框架来实现。下面是使用SofaGo框架的基本步骤: 1. 安装SofaGo框架:使用go get命令安装SofaGo框架,具体命令如下: ``` go get github.com/alipay/sofa-mosn ``` 2. 创建SofaGo应用:创建一个新的Go应用,并在代码中导入SofaGo框架相关的包,如下所示: ``` import ( "github.com/alipay/sofa-mosn" "github.com/alipay/sofa-mosn/pkg/protocol/rpc/sofarpc" ) ``` 3. 配置SofaGo应用:在代码中设置SofaGo应用的配置信息,如监听地址、协议类型、日志级别等,可以通过配置文件或代码实现,如下所示: ``` config := mosn.NewConfigBuilder(). SetListenerConfigs(listenerConfig). Build() ``` 4. 实现SofaGo服务:在代码中实现SofaGo服务,并在服务注册中心中注册,如下所示: ``` type HelloServiceImpl struct {} func (p HelloServiceImpl) SayHello(req *sofarpc.Request) *sofarpc.Response { resp := &sofarpc.Response{ ProtocolCode: sofarpc.PROTOCOL_CODE_V1, ResponseCode: sofarpc.RESPONSE_STATUS_SUCCESS, ResponseTimeMillis: uint32(time.Now().UnixNano() / 1e6), ResponseProps: make(map[string]string), RespObject: []interface{}{"Hello, " + req.GetRPCRequest().ServiceName}, } return resp } func main() { service := mosn.NewServiceConfigBuilder(). RegisterService("com.alipay.sofa.rpc.test.HelloService", new(HelloServiceImpl)). Build() } ``` 5. 运行SofaGo应用:使用go run命令运行SofaGo应用,如下所示: ``` go run main.go ``` 以上是使用SofaGo框架开发Go语言分布式应用的基本步骤,具体实现方式可以根据具体需求进行调整。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值