csp 201903-5 317号子任务
这个只是用来记录含辛茹苦的优化过程,具体讲解在这里:
201903-5 317号子任务(100分)
测试用例:
7 6 2
1 0 1 0 1 1 0
1 4 1
1 2 3
2 4 4
2 3 5
2 5 7
6 7 5
30分 弗洛伊德:
#include <iostream>
#include <iostream>
#include <vector>
#include <algorithm>
#include <queue>
#define INF 0x7fffffff
using namespace std;
int main()
{
int n,m,k;
while(cin>>n>>m>>k){
vector<bool> important;
for(int i = 0; i < n; i++){
int temp;
cin>> temp;
if(temp == 1){
important.push_back(true);
}else{
important.push_back(false);
}
}
int* eage = new int[n*n];
//init
for(int i = 0; i < n; i++){
for(int j = 0; j < n; j++){
if(i == j){
eage[i*n+j] = 0;
}else{
eage[i*n+j] = INF;
}
}
}
for(int j = 0; j < m; j++){
int left;
int right;
int weight;
cin>>left>>right>>weight;
if(weight< eage[(left-1)*n+right-1]){
eage[(left-1)*n+right-1] = weight;
eage[(right-1)*n+left-1] = weight;
}
}
//int* dp = new int[n*n];
//cal
for(int p = 0; p < n;p++){
for(int i = 0; i < n; i++){
for(int j = 0; j < i; j++){
if(eage[i*n+p] != INF && eage[p*n+j] != INF){
eage[i*n+j] = min(eage[i*n+p]+eage[p*n+j],eage[i*n+j]);
eage[j*n+i] = eage[i*n+j];
}
}
}
}
for(int i = 0; i < n;i++){
int count = 0;
priority_queue<int,vector<int>,less<int> > myqueue;
for(int j = 0; j < n;j++){
if(important[j]){
int weight = eage[i*n+j];
if(count >= k){
if(weight < myqueue.top()){
myqueue.pop();
myqueue.push(weight);
}
}else{
if(weight != INF){
myqueue.push(weight);
count++;
}
}
}
}
int size = myqueue.size();
int sum = 0;
for(int p = 0; p <size && p < k; p++){
sum += myqueue.top();
myqueue.pop();
}
cout << sum<<endl;
}
delete [] eage;
}
return 0;
}
30分 迪杰斯特拉:
#include <iostream>
#include <iostream>
#include <vector>
#include <algorithm>
#include <queue>
#define INF 0x7fffffff
using namespace std;
int main()
{
int n,m,k;
while(cin>>n>>m>>k){
vector<bool> important;
for(int i = 0; i < n; i++){
int temp;
cin>> temp;
if(temp == 1){
important.push_back(true);
}else{
important.push_back(false);
}
}
int* eage = new int[n*n];
//init
for(int i = 0; i < n; i++){
for(int j = 0; j < n; j++){
if(i == j){
eage[i*n+j] = 0;
}else{
eage[i*n+j] = INF;
}
}
}
for(int j = 0; j < m; j++){
int left;
int right;
int weight;
cin>>left>>right>>weight;
if(weight< eage[(left-1)*n+right-1]){
eage[(left-1)*n+right-1] = weight;
eage[(right-1)*n+left-1] = weight;
}
}
int* mindis = new int[n*n];
//cal
for(int i = 0; i < n; i++){
for(int j = 0; j < n; j++){
mindis[i*n+j] = eage[i*n+j];
}
}
for(int i = 0; i< n; i++){
//int* currdis = new int[n];
vector<int> currdis;
vector<bool> visit;
for(int j = 0; j < n; j++){
//currdis[j] = dis[i*n+j];
currdis.push_back(eage[i*n+j]);
visit.push_back(false);
}
int min = INF;
int postion = -1;
while(true){
//min one
for(int j = 0; j < n; j++){
if(!visit[j] && currdis[j] < min){
min = currdis[j];
postion = j;
}
}
if(min == INF){
break;
}
//visit
visit[postion] = true;
mindis[i*n+postion] = min;
mindis[postion*n+i] = mindis[i*n+postion];
//update
for(int j = 0; j < n; j++){
if(!visit[j]){
if(eage[postion*n+j] != INF && min+eage[postion*n+j] < currdis[j]){
currdis[j] = min+eage[postion*n+j];
}
}
}
min = INF;
}
}
for(int i = 0; i < n;i++){
int count = 0;
priority_queue<int,vector<int>,less<int> > myqueue;
for(int j = 0; j < n;j++){
if(important[j]){
int weight = mindis[i*n+j];
if(count >= k){
if(weight < myqueue.top()){
myqueue.pop();
myqueue.push(weight);
}
}else{
if(weight != INF){
myqueue.push(weight);
count++;
}
}
}
}
int size = myqueue.size();
int sum = 0;
for(int p = 0; p <size && p < k; p++){
sum += myqueue.top();
myqueue.pop();
}
cout << sum<<endl;
}
delete [] mindis;
delete [] eage;
}
return 0;
}
只用了行星发动点,依旧是30分呜呜呜
#include <iostream>
#include <iostream>
#include <vector>
#include <algorithm>
#include <queue>
#define INF 0x7fffffff
using namespace std;
int main()
{
int n,m,k;
while(cin>>n>>m>>k){
vector<bool> important;
for(int i = 0; i < n; i++){
int temp;
cin>> temp;
if(temp == 1){
important.push_back(true);
}else{
important.push_back(false);
}
}
int* eage = new int[n*n];
//init
for(int i = 0; i < n; i++){
for(int j = 0; j < n; j++){
if(i == j){
eage[i*n+j] = 0;
}else{
eage[i*n+j] = INF;
}
}
}
for(int j = 0; j < m; j++){
int left;
int right;
int weight;
cin>>left>>right>>weight;
if(weight< eage[(left-1)*n+right-1]){
eage[(left-1)*n+right-1] = weight;
eage[(right-1)*n+left-1] = weight;
}
}
int* mindis = new int[n*n];
//cal
for(int i = 0; i < n; i++){
for(int j = 0; j < n; j++){
mindis[i*n+j] = eage[i*n+j];
}
}
for(int i = 0; i< n; i++){
if(!important[i]){
continue;
}
vector<int> currdis;
vector<bool> visit;
for(int j = 0; j < n; j++){
currdis.push_back(eage[i*n+j]);
visit.push_back(false);
}
int min = INF;
int postion = -1;
while(true){
//min one
for(int j = 0; j < n; j++){
if(!visit[j] && currdis[j] < min){
min = currdis[j];
postion = j;
}
}
if(min == INF){
break;
}
//visit
visit[postion] = true;
mindis[i*n+postion] = min;
mindis[postion*n+i] = mindis[i*n+postion];
//update
for(int j = 0; j < n; j++){
if(!visit[j]){
if(eage[postion*n+j] != INF && min+eage[postion*n+j] < currdis[j]){
currdis[j] = min+eage[postion*n+j];
}
}
}
min = INF;
}
}
for(int i = 0; i < n;i++){
int count = 0;
priority_queue<int,vector<int>,less<int> > myqueue;
for(int j = 0; j < n;j++){
if(important[j]){
int weight = mindis[i*n+j];
if(count >= k){
if(weight < myqueue.top()){
myqueue.pop();
myqueue.push(weight);
}
}else{
if(weight != INF){
myqueue.push(weight);
count++;
}
}
}
}
int size = myqueue.size();
int sum = 0;
for(int p = 0; p <size && p < k; p++){
sum += myqueue.top();
myqueue.pop();
}
cout << sum<<endl;
}
delete [] mindis;
delete [] eage;
}
return 0;
}
我继续改,用了heap的迪杰斯特拉,30分
#include <iostream>
#include <vector>
#include <algorithm>
#include <queue>
#define INF 0x7fffffff
using namespace std;
struct node{
int id;
int dis;
};
struct cmp{
bool operator()(const node& a,const node& b){
return a.dis > b.dis;
}
};
int main()
{
int n,m,k;
while(cin>>n>>m>>k){
vector<int> important;
for(int i = 0; i < n; i++){
int temp;
cin>> temp;
if(temp == 1){
important.push_back(i);
}
}
int* eage = new int[n*n];
//init
for(int i = 0; i < n; i++){
for(int j = 0; j < n; j++){
if(i == j){
eage[i*n+j] = 0;
}else{
eage[i*n+j] = INF;
}
}
}
for(int j = 0; j < m; j++){
int left;
int right;
int weight;
cin>>left>>right>>weight;
if(weight< eage[(left-1)*n+right-1]){
eage[(left-1)*n+right-1] = weight;
eage[(right-1)*n+left-1] = weight;
}
}
int* mindis = new int[n*n];
//cal
for(int w = 0; w< important.size(); w++){
int i = important[w];
//vector<int> currdis;
priority_queue<node,vector<node>,cmp> heap;
vector<bool> visit;
for(int j = 0; j < n; j++){
//currdis.push_back(eage[i*n+j]);
node tempnode;
tempnode.id = j;
tempnode.dis = eage[i*n+j];
heap.push(tempnode);
visit.push_back(false);
}
while(!heap.empty()){
//min one
node minnode = heap.top();
heap.pop();
int postion = minnode.id;
int min = minnode.dis;
if(visit[postion]){
continue;
}
//visit
visit[postion] = true;
mindis[i*n+postion] = min;
mindis[postion*n+i] = mindis[i*n+postion];
if(min == INF){
continue;
}
//update
for(int j = 0; j < n; j++){
if(!visit[j] && eage[postion*n+j] != INF){
node tempnode;
tempnode.id = j;
tempnode.dis = min+eage[postion*n+j];
heap.push(tempnode);
}
}
}
}
for(int i = 0; i < n;i++){
int count = 0;
priority_queue<int,vector<int>,less<int> > myqueue;
for(int w = 0; w < important.size();w++){
int j = important[w];
int weight = mindis[i*n+j];
if(count >= k){
if(weight < myqueue.top()){
myqueue.pop();
myqueue.push(weight);
}
}else{
if(weight != INF){
myqueue.push(weight);
count++;
}
}
}
int size = myqueue.size();
int sum = 0;
for(int p = 0; p <size && p < k; p++){
sum += myqueue.top();
myqueue.pop();
}
cout << sum<<endl;
}
delete [] mindis;
delete [] eage;
}
return 0;
}
啊啊啊啊100分!!!!!
#include <iostream>
#include <vector>
#include <algorithm>
#include <queue>
#define INF 0x7fffffff
using namespace std;
struct node{
int id;
int dis;
};
struct cmp{
bool operator()(const node& a,const node& b){
return a.dis > b.dis;
}
};
int main()
{
int n,m,k;
while(scanf("%d %d %d",&n,&m,&k)!= EOF){
vector<int> important;
for(int i = 0; i < n; i++){
int temp;
//cin>> temp;
scanf("%d",&temp);
if(temp == 1){
important.push_back(i);
}
}
//int* eage = new int[n*n];
vector<vector<node> > eage(n);
//init
for(int i = 0; i < n; i++){
node temp;
temp.id = i;
temp.dis = 0;
eage[i].push_back(temp);
}
for(int j = 0; j < m; j++){
int left;
int right;
int weight;
//cin>>left>>right>>weight;
scanf("%d %d %d",&left,&right,&weight);
// if(weight< eage[(left-1)*n+right-1]){
// eage[(left-1)*n+right-1] = weight;
// eage[(right-1)*n+left-1] = weight;
// }
node temp;
temp.id = right-1;
temp.dis = weight;
eage[left-1].push_back(temp);
temp.id = left-1;
eage[right-1].push_back(temp);
}
int* mindis = new int[n*n];
//cal
for(int w = 0; w< important.size(); w++){
int i = important[w];
//vector<int> currdis;
priority_queue<node,vector<node>,cmp> heap;
vector<bool> visit;
for(int j = 0; j < n; j++){
visit.push_back(false);
}
for(int j = 0; j < eage[i].size(); j++){
heap.push(eage[i][j]);
}
while(!heap.empty()){
//min one
node minnode = heap.top();
heap.pop();
int postion = minnode.id;
int min = minnode.dis;
if(visit[postion]){
continue;
}
//printf("from: %d;min: %d;position: %d\n",i,min,postion);
//visit
visit[postion] = true;
mindis[i*n+postion] = min;
mindis[postion*n+i] = mindis[i*n+postion];
//update
for(int j = 0; j < eage[postion].size(); j++){
if(!visit[eage[postion][j].id]){
node tempnode;
tempnode.id = eage[postion][j].id;
tempnode.dis = min+eage[postion][j].dis;
heap.push(tempnode);
}
}
}
for(int j = 0; j < n; j++){
if(!visit[j]){
mindis[i*n+j] = INF;
mindis[j*n+i] = mindis[i*n+j];
}
}
}
for(int i = 0; i < n;i++){
int count = 0;
priority_queue<int,vector<int>,less<int> > myqueue;
for(int w = 0; w < important.size();w++){
int j = important[w];
int weight = mindis[i*n+j];
if(count >= k){
if(weight < myqueue.top()){
myqueue.pop();
myqueue.push(weight);
}
}else{
if(weight != INF){
myqueue.push(weight);
count++;
}
}
}
int size = myqueue.size();
int sum = 0;
for(int p = 0; p <size && p < k; p++){
sum += myqueue.top();
myqueue.pop();
}
//cout << sum<<endl;
printf("%d\n",sum);
}
delete [] mindis;
}
return 0;
}