HDU 4370 0 or 1 (最短路)
作者:互联网
题意:
给出一个n*n的矩阵C,要求构造一个满足条件的n*n的01矩阵X,使得最小。
题解:
没错。。。第一眼怎么都觉得就是普通贪心,然后果断WA了。
正解是最短路。
由X矩阵的特点,可以看作是n个点的邻接矩阵,X[i][j]为1表示存在i到j的路径,C[i][j]就表示该路径的花费。
对X矩阵的要求可转化为,1号点出度为1(入度可能为0或1,更多显然),n号点入度为1(出度可以为0或1),其他点入度等于出度。
那么所求的答案就可能是,1号点直接到n号点的最短距离,或1号点形成一个回到1号点的环的最短距离+n号点形成一个回到n号点的环的最短距离。
代码:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define db double
#define m_p make_pair
#define p_b push_back
#define For(i,a,b) for(int i=a;i<=b;i++)
#define ls (root<<1)
#define rs ((root<<1)|1)
#define mst(a,b) memset(a,b,sizeof(a))
const int MAXN=3e2+5;
const db eps=1e-8;
const int INF=0x3f3f3f3f;
const int mod=1e9+7;
const int seed=131;
int a[MAXN][MAXN];
int dis[MAXN];
bool vis[MAXN];
struct Edge{
int v,w;
Edge(int _v=0,int _w=0):v(_v),w(_w){}
bool operator<(const Edge &p)const{
return w>p.w;
}
};
priority_queue<Edge> pq;
void dij(int s,int n){
mst(vis,0);
For(i,1,n) if(i!=s) dis[i]=a[s][i],pq.push(Edge(i,dis[i]));
dis[s]=INF;
while(!pq.empty()){
int u=pq.top().v;
pq.pop();
if(vis[u]) continue;
vis[u]=1;
for(int i=1;i<=n;i++){
if(i!=u&&dis[i]>dis[u]+a[u][i]){
dis[i]=dis[u]+a[u][i];
pq.push(Edge(i,dis[i]));
}
}
}
}
int main(){
// freopen("in.txt","r",stdin);
int n;
while(~scanf("%d",&n)){
For(i,1,n){
For(j,1,n){
scanf("%d",&a[i][j]);
}
}
dij(1,n);
int ans=dis[n],tmp=dis[1];
dij(n,n);
tmp+=dis[n];
ans=min(ans,tmp);
cout<<ans<<"\n";
}
return 0;
}
标签:HDU,pq,int,短路,矩阵,4370,define,号点,dis 来源: https://blog.csdn.net/qq_38515845/article/details/89736865