隐藏页面特效

SPOJ OPTM - Optimal Marks

OPTM - Optimal Marks

no tags 

 

 

You are given an undirected graph G(V, E). Each vertex has a mark which is an integer from the range [0..231 – 1]. Different vertexes may have the same mark.

For an edge (u, v), we define Cost(u, v) = mark[u] xor mark[v].

Now we know the marks of some certain nodes. You have to determine the marks of other nodes so that the total cost of edges is as small as possible.

 

Input

The first line of the input data contains integer T (1 ≤ T ≤ 10) - the number of testcases. Then the descriptions of T testcases follow.

First line of each testcase contains 2 integers N and M (0 < N <= 500, 0 <= M <= 3000). N is the number of vertexes and M is the number of edges. Then M lines describing edges follow, each of them contains two integers u, v representing an edge connecting u and v.

Then an integer K, representing the number of nodes whose mark is known. The next K lines contain 2 integers u and p each, meaning that node u has a mark p. It’s guaranteed that nodes won’t duplicate in this part.

Output

For each testcase you should print N lines integer the output. The Kth line contains an integer number representing the mark of node K. If there are several solutions, you have to output the one which minimize the sum of marks. If there are several solutions, just output any of them.

Example

Input: 1 3 2 1 2 2 3 2 1 5 3 100 Output: 5 4 100

 

 

 

 

 

 Select Code

#include<cstdio> #include<cstring> #include<iostream> using namespace std; const int N=3e4+5; const int M=1e6+5; struct edge{int v,next,cap;}e[M];int tot=1,head[N]; int mark[N],ans[N],dis[N],q[N*10];bool vis[N]; int cas,n,m,k,S,T,a[N][2]; inline int read(){ int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } inline void add(int x,int y,int z1,int z2=0){ e[++tot].v=y;e[tot].cap=z1;e[tot].next=head[x];head[x]=tot; e[++tot].v=x;e[tot].cap=z2;e[tot].next=head[y];head[y]=tot; } inline bool bfs(){ for(int i=S;i<=T;i++) dis[i]=-1; int h=0,t=1;q[t]=S;dis[S]=0; while(h!=t){ int x=q[++h]; for(int i=head[x];i;i=e[i].next){ if(e[i].cap&&dis[e[i].v]==-1){ dis[e[i].v]=dis[x]+1; if(e[i].v==T) return 1; q[++t]=e[i].v; } } } return 0; } int dfs(int x,int f){ if(x==T) return f; int used=0,t; for(int i=head[x];i;i=e[i].next){ if(e[i].cap&&dis[e[i].v]==dis[x]+1){ t=dfs(e[i].v,min(e[i].cap,f)); e[i].cap-=t;e[i^1].cap+=t; used+=t;f-=t; if(!f) return used; } } if(!used) dis[x]=-1; return used; } inline int dinic(){ int res=0; while(bfs()) res+=dfs(S,2e9); return res; } void init(){ n=read();m=read();S=0;T=n+1; memset(mark,-1,n+1<<2); for(int i=1;i<=m;i++) a[i][0]=read(),a[i][1]=read(); k=read(); for(int i=1,x,y;i<=k;i++) x=read(),y=read(),mark[x]=y; } void DFS(int x,int d){ vis[x]=1; ans[x]+=d; for(int i=head[x];i;i=e[i].next){ if(!vis[e[i].v]&&e[i].cap){ DFS(e[i].v,d); } } } void work(){ memset(ans,0,n+1<<2); int bite=1; for(;;){ tot=1;memset(head,0,n+2<<2); for(int i=1;i<=m;i++) add(a[i][0],a[i][1],1,1); bool flag=0; for(int i=1;i<=n;i++){ if(~mark[i]){ if(mark[i]>=1) flag=1; if(mark[i]&1){ add(S,i,2e9); } else{ add(i,T,2e9); } mark[i]>>=1; } } if(!flag) break; dinic(); memset(vis,0,sizeof vis); DFS(S,bite);bite<<=1; } for(int i=1;i<=n;i++) printf("%d ",ans[i]);putchar('\n'); } int main(){ cas=read(); while(cas--) init(),work(); return 0; }

 

 

__EOF__

本文作者shenben
本文链接https://www.cnblogs.com/shenben/p/6607401.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   神犇(shenben)  阅读(319)  评论(0编辑  收藏  举报
编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
点击右上角即可分享
微信分享提示