Network Planning

Network Planning
Time Limit: 1000ms, Special Time Limit:2500ms, Memory Limit:65536KB
Total submit users: 12, Accepted users: 10
Problem 12930 : No special judgement
Problem description

In petroleum retail industry, the locations of service stations are very important to the profit of their company. To maximize the profit, the company uses the concept of “Network Planning” to choose where to build new service stations.

You are a consultant of this company. This company gives you the data which consists of the number of cities and how are they connected, number of liters of fuel demand, list of cities that already had a service station, and a total number of new service stations to be constructed in their plan this year.

Of course, the result that they need from you is “which cities should they construct new service stations to maximize their profit”. Sounds simple, isn’t it?

Here is a list of what you might need to know.

• There will be N cities in this country. Each city can own only one service station.

• Assuming each service station is able to supply unlimited fuel demand.

• Each service station will supply 70% of fuel demand (in liters) within its city, plus 10% of each neighboring city’s demand regardless of a fact that whether neighboring cities have their own service station or not.

• For example, if City A, City B, and City C are all connected; City A and City B has their own service stations, then City A will supply 70% fuel demand of itself plus 10% from City B and 10% from City C. So does City B.

• Due to geographical constraints, each city will have no more than three neighboring cities.

• Last, but not least, their total revenue is a direct variation of total fuel demand that they can supply.


Input

First line of input is a number of test cases T ≤ 10. Each test case start with the number of cities N (1 ≤ N ≤ 100000). Following N lines has an Integer Di (0 ≤ Di ≤ 1000) the fuel demand in each city. Next line contains an integer E number of edges.

Following E lines has 2 integers C1 and C2, describe bi-directionally neighboring cities. There will not be any duplicated edges in the input (i.e. if there is an edge for (C1, C2), there will not be an edge for (C2, C1) in the same input set). Also note that all cities will be numbering from 1 to N.

Next line contains an integer S (0 ≤ S < N) the number of existing service stations

Following S lines has an integer C the city which already owned service station

Last line contains an integer M (1 ≤ M ≤ N?S) an exact number of new service stations they must construct this year.


Output

For each test case, display two lines of output.

First line display a positive integer (using general rounding rules) the maximum total fuel demand they can supply including from both existing service stations and new service stations at the optimal cities.

Second line display a list of the optimal cities that they must construct new service stations, given space-separated and in increasing order. The cities with existing service stations are not counted into this list. If there is more than one possible solution, output the one that is first in lexicographical order.


Sample Input
2
3
100
200
300
3
1 2
2 3
3 1
1
1
1
5
326
200
200
100
400
5
1 2
1 3
2 4
3 4
4 5
1
4
3
Sample Output
360
3
891
1 2 5
Judge Tips

#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#define maxn 100010
using namespace std;

int a[maxn];
int res[maxn];
bool vis[maxn];
struct NOde
{
	double value;
	int id;
}b[maxn];
struct node
{
	int u,v;
}edge[maxn];

template<class T>
inline char read(T &n){
    T x = 0, tmp = 1; char c = getchar();
    while((c < '0' | c > '9') && c != '-' && c != EOF) c = getchar();
    if(c == '-') c = getchar(), tmp = -1;
    while(c >= '0' && c <= '9') x *= 10, x += (c - '0'),c = getchar();
    n = x*tmp;
    return c;
}
template <class T>
inline void write(T n) {
    if(n < 0) {
        putchar('-');
        n = -n;
    }
    int len = 0,data[20];
    while(n) {
        data[len++] = n%10;
        n /= 10;
    }
    if(!len) data[len++] = 0;
    while(len--) putchar(data[len]+48);
}

bool cmp(NOde a,NOde b)//double的比较大小 ,改善id问题 
{
	if(a.value-b.value<0.00000001 && a.value-b.value>-0.0000001 )
	return a.id<b.id;
	if(a.value-b.value>0.00000001 )
	return true;
	else
	return false;
}

int main()
{
	int cas;
	read(cas);
	while(cas--)
	{
		memset(vis,0,sizeof(vis));
		int N;
		scanf("%d",&N);
		for(int i=1;i<=N;i++)
		{
			read(a[i]);
			b[i].value=0.7*a[i];
			b[i].id=i;	
		}	
		int E;
	    read(E);
	 	for(int i=1;i<=E;i++)
		{
		read(edge[i].u);read(edge[i].v);
		b[edge[i].u].value+=0.1*a[edge[i].v];
		b[edge[i].v].value+=0.1*a[edge[i].u];
	    }
	    int s;
		read(s);	double result=0;
		for(int i=1;i<=s;i++)
		{
			int x;
		    read(x);
			vis[x]=true;
			result+=b[x].value;
		}
		int newx;
		read(newx);
		sort(b+1,b+1+N,cmp);
	    int top=0;
		for(int i=1;i<=N&&newx;i++)
		{
		if(!vis[b[i].id])
		{
	     result+=b[i].value;
	     res[++top]=b[i].id;
		 newx--; 
	    }
	    } 
	    result=(int)(result+0.5);
		printf("%.lf\n",result);//四舍五入
		sort(res+1,res+top+1);
		for(int i=1;i<top;i++)
		{
			printf("%d ",res[i]);
		}
		printf("%d\n",res[top]);
	}
	
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值