HOJ 2816 Power Line
Power Line
Time limit:
5sec.
Submitted:
269
Memory limit:
64M
Accepted:
84
Source: 2009 China North East Local Contest
Problem Description While DUT is hosting this NECPC Contest, in order to control the expenditure, careful considerations should be given in many respects, such as the layout of the contest venue. When the contest venue is arranged, each computer requires power input. While the layout of computers and power-points are already fixed, some lines have to be purchased to link the computers with power-points. And, Raven finds out that it is cheaper to buy power lines of the same length than to buy lines of different lengths, so he would buy all the lines with the same length. If Raven wants to save money, would you help him? Input Details The first line of the input contains an integer T, which indicates the number of test cases. For each test case, there are three positive integers in the first row, n, m, p (0 <= n, m <= 200,0 < p < 100). It means that there are n computers and m power-points. The power line costs ¥p per unit. In the following n rows, i-th line has m positive integers indicating the distances between the i-th computer and all the power points. The distance is less than 10000. In the last row, there are m positive integers, ci (0 < ci < 5,0 <= i < m), showing No.i power-point can provide power to ci computers in total. Output Details For each case, if the layout of computers and power lines are not reasonable, which means you cannot provide power to every computer, just output -1. Otherwise, output the lowest total price for power lines. Sample Input
1
2 2 1
1 3
2 2
1 1
Sample Output 4
Hint: You many link the first computer with the first power-points, and link the second computer with the second power-points. This will cost 4(2*2). 2점+다중 일치
물, 물이 더 건강해요.
#include
#include
const int inf=0x7fffffff;
int mat[500][500],link[500][500];
bool map[500][500],usedif[500];
int n,m,p,rmin,rmax;
int lim[500];
bool flag;
bool can(int t)
{
for(int i=1; i<=m; i++)
{
if(usedif[i]==0&&map[t][i])
{
usedif[i]=1;
if(link[i][0]
link[i][++link[i][0]]=t;
return true;
}
else
{
for(int j=1; j<=link[i][0]; j++)
if(can(link[i][j]))
{
link[i][j]=t;
return true;
}
}
}
}
return false;
}
bool check(int limit)
{
memset(map,false,sizeof(map));
for(int i=1; i<=m; i++) link[i][0]=0;
for(int i=1; i<=n; i++)
for(int j=1; j<=m; j++)
if(mat[i][j]<=limit) map[i][j]=true;
for(int i=1; i<=n; i++)
{
memset(usedif,0,sizeof(usedif));
if(!can(i)) return false;
}
return true;
}
int find()
{
int high=rmax,low=rmin;
int ans=high;
flag=false;
while(low
int mid=(low+high)>>1;
if(check(mid))
{
flag=true;
if(mid
}
else low=mid+1;
}
return ans;
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d%d%d",&n,&m,&p);
rmin=inf;
rmax=-1;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
scanf("%d",&mat[i][j]);
if(mat[i][j]
}
for(int i=1;i<=m;i++) scanf("%d",&lim[i]);
int t=find();
if(flag) printf("%d/n",p*n*t);
else printf("-1/n");
}
return 0;
}
네트워크 스트리밍, 0.2S 정도의 시간 소모
#include
#include
const int N=1510;
const int M=60001;
const int inf=0x7fffffff;
int head[N];
int lim[N];
int map[N][N];
struct Edge
{
int v,next,w;
} edge[M];
int cnt,s,t;
int n,m,p;
bool flag;
int rmin,rmax,nn;
void addedge(int u,int v,int w)
{
edge[cnt].v=v;
edge[cnt].w=w;
edge[cnt].next=head[u];
head[u]=cnt++;
edge[cnt].v=u;
edge[cnt].w=0;
edge[cnt].next=head[v];
head[v]=cnt++;
}
int sap()
{
int pre[N],cur[N],dis[N],gap[N];
int flow=0,aug=inf,u;
bool flag;
for(int i=0; i
cur[i]=head[i];
gap[i]=dis[i]=0;
}
gap[s]=n;
u=pre[s]=s;
while(dis[s]
flag=0;
for(int &j=cur[u]; j!=-1; j=edge[j].next)
{
int v=edge[j].v;
if(edge[j].w>0&&dis[u]==dis[v]+1)
{
flag=1;
if(edge[j].w
u=v;
if(u==t)
{
flow+=aug;
while(u!=s)
{
u=pre[u];
edge[cur[u]].w-=aug;
edge[cur[u]^1].w+=aug;
}
aug=inf;
}
break;
}
}
if(flag) continue;
int mindis=n;
for(int j=head[u]; j!=-1; j=edge[j].next)
{
int v=edge[j].v;
if(edge[j].w>0&&dis[v]
mindis=dis[v];
cur[u]=j;
}
}
if((--gap[dis[u]])==0)
break;
gap[dis[u]=mindis+1]++;
u=pre[u];
}
return flow;
}
bool check(int limit)
{
cnt=0;
memset(head,-1,sizeof(head));
for(int i=1;i<=nn;i++) addedge(s,i,1);
for(int i=1;i<=m;i++) addedge(i+nn,t,lim[i]);
for(int i=1;i<=nn;i++)
for(int j=1;j<=m;j++)
if(map[i][j]<=limit) addedge(i,j+nn,1);
if(sap()==nn) return true;
return false;
}
int solve()
{
flag=false;
int head=rmin,end=rmax;
int ans=end;
while(head
int mid=(head+end)>>1;
if(check(mid))
{
if(ans>mid) ans=mid;
flag=true;
end=mid;
}
else head=mid+1;
}
return ans;
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d%d%d",&n,&m,&p);
s=0;
t=n+m+1;
rmin=inf;
rmax=-1;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
scanf("%d",&map[i][j]);
if(map[i][j]
}
for(int i=1;i<=m;i++) scanf("%d",&lim[i]);
nn=n;
n=n+m+2;
int tt=solve();
if(flag) printf("%d/n",p*nn*tt);
else printf("-1/n");
}
return 0;
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
React Native Reanimated 2 레이아웃 애니메이션 예제은 라이브러리를 사용하여 React Native 구성 요소의 시작, 종료 및 레이아웃 변경에 애니메이션을 적용하는 가장 쉬운 방법입니다. 좋아보이죠? 그리고 구현하기가 매우 쉽습니다! TLDR You can find...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.