POJ 1062 图论入门第十题

    技术2022-05-20  40

         题目大意:这一道中文题、当然中文题也有读不懂的时候、比如这句:“但是如果他和某个地位较低的人进行了交易,地位较高的的人不会再和他交易,他们认为这样等于是间接接触,反过来也一样。”我就想错了、应该说想麻烦了。搞了半天连个样列都过不了、索性最后放弃了。看了网上别人的题解,说要对限制范围进行枚举,这样既满足了限制条件又避免了通过中间交换而形成隔人差值。感觉很犀利!

         题目分析:手一激动全写在题目大意里面了。

         代码就是算法:

     

    #include<cstdio> #include<cstring> #include<algorithm> using namespace std; #define init(a,what) memset(a,what,sizeof(a)) #define read freopen("zx.in","r",stdin) #define write freopen("zx.out","w",stdout) const int INF=0x3f3f3f3f; const int MAXN=100+10; int max_lev,nnum,mincost,dist[MAXN][MAXN]; int inlev[MAXN],value[MAXN],curnum[MAXN]; bool lev[MAXN]; int dijkstra() { int minsum=INF,sumcost,cur[MAXN]; bool vis[MAXN]; init(vis,false); for(int i=1;i<=nnum;i++) cur[i]=(i==1 ? 0 : INF); for(int i=1;i<=nnum;i++) { int k,minn=INF; for(int j=1;j<=nnum;j++) if(!vis[j] && cur[j]<=minn && inlev[j]) minn=cur[k=j]; vis[k]=true; for(int j=1;j<=nnum;j++) if(inlev[j]) cur[j]=min(cur[j],cur[k]+dist[k][j]); } for(int i=1;i<=nnum;i++) { sumcost=cur[i]+value[i]; if(sumcost<minsum) minsum=sumcost; } return minsum; } int main() { read, write; while(scanf("%d%d",&max_lev,&nnum)!=EOF) { mincost=INF; init(dist,INF); for(int i=1;i<=nnum;i++) { scanf("%d%d%d",&value[i],&lev[i],&curnum[i]); for(int j=1;j<=curnum[i];j++) { int k; scanf("%d",&k); scanf("%d",&dist[i][k]); } } //每次求一个范围,在这个可行的范围内进行dijkstra算法 for(int i=0;i<=max_lev;i++) { init(inlev,false); for(int j=1;j<=nnum;j++) if(lev[j]>=lev[1]-max_lev+i && lev[j]<=lev[1]+i) inlev[j]=true; int cost=dijkstra(); if(mincost>cost) mincost=cost; } printf("%d/n",mincost); } return 0; }


    最新回复(0)