UVA11671题解
题意简述
给你一个大小为
题目分析
这个题是一个比较裸的差分约束,但是条件需要一些转化。首先很明显,题目中对矩阵操作没有先后之分,因此最终每个位置值的变化可以直接拆分为行与列分别加上减去的数之和。我们可以分别设两个数组 0
,那么代表 +
,那么代表 -
,那么代表
首先,从题目中得到的条件都是加法,因此为了将其转化为减法,可以将
至此,我们求出了满足要求的一组解
最后给出代码:
#include<bits/stdc++.h> using namespace std; int hd[210],n,c,d[210],v[210],s[210],cnt,sm; char a[210]; queue<int>q,t; struct nd { int nt,v,w; }e[40010]; void adde(int u,int v,int w) { e[c].v=v; e[c].w=w; e[c].nt=hd[u]; hd[u]=c++; } bool spfa() //差分约束中的最短路 { q=t; for(int i=1;i<=2*n;i++) q.push(i),d[i]=0,v[i]=1,s[i]=1; while(q.size()) { int t=q.front(); q.pop(); for(int i=hd[t];i!=-1;i=e[i].nt) { int vt=e[i].v; if(d[vt]>d[t]+e[i].w) { d[vt]=d[t]+e[i].w; if(v[vt]==0) { q.push(vt); v[vt]=1; s[vt]++; if(s[vt]>2*n+1) return 0;//点入队次数过多,有负环 } } } v[t]=0; } return 1;//无负环 } int main() { while(scanf("%d",&n),n!=-1) { cnt++; c=0; memset(hd,-1,sizeof hd); for(int i=1;i<=n;i++) { scanf("%s",a+1); for(int j=1;j<=n;j++) { //加边 if(a[j]=='+') adde(j+n,i,-1); else if(a[j]=='-') adde(i,j+n,-1); else adde(i,j+n,0),adde(j+n,i,0); } } printf("Case %d: ",cnt); if(spfa()) { sm=0; sort(d+1,d+2*n+1);//排序以方便求中位数。 for(int i=1;i<=2*n;i++) sm+=abs(d[i]-d[n]);//取中位数 d[n] 作为 Δ。 printf("%d\n",sm); } else printf("-1\n"); } return 0; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 因为Apifox不支持离线,我果断选择了Apipost!
· 通过 API 将Deepseek响应流式内容输出到前端